Bug Summary

File:tools/lldb/tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.cpp
Warning:line 1412, column 5
Value stored to 'bOk' is never read

Annotated Source Code

1//===-- MICmnLLDBDebuggerHandleEvents.cpp -----------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10// Third party headers:
11#include "lldb/API/SBAddress.h"
12#include "lldb/API/SBBreakpoint.h"
13#include "lldb/API/SBCommandInterpreter.h"
14#include "lldb/API/SBCommandReturnObject.h"
15#include "lldb/API/SBEvent.h"
16#include "lldb/API/SBProcess.h"
17#include "lldb/API/SBStream.h"
18#include "lldb/API/SBTarget.h"
19#include "lldb/API/SBThread.h"
20#include "lldb/API/SBUnixSignals.h"
21#ifdef _WIN32
22#include <io.h> // For the ::_access()
23#else
24#include <unistd.h> // For the ::access()
25#endif // _WIN32
26
27// In-house headers:
28#include "MICmnLLDBDebugSessionInfo.h"
29#include "MICmnLLDBDebugger.h"
30#include "MICmnLLDBDebuggerHandleEvents.h"
31#include "MICmnLog.h"
32#include "MICmnMIOutOfBandRecord.h"
33#include "MICmnMIResultRecord.h"
34#include "MICmnMIValueConst.h"
35#include "MICmnMIValueList.h"
36#include "MICmnResources.h"
37#include "MICmnStreamStderr.h"
38#include "MICmnStreamStdout.h"
39#include "MIDriver.h"
40#include "MIUtilDebug.h"
41#include "Platform.h" // for PATH_MAX
42
43//++
44//------------------------------------------------------------------------------------
45// Details: CMICmnLLDBDebuggerHandleEvents constructor.
46// Type: Method.
47// Args: None.
48// Return: None.
49// Throws: None.
50//--
51CMICmnLLDBDebuggerHandleEvents::CMICmnLLDBDebuggerHandleEvents() {}
52
53//++
54//------------------------------------------------------------------------------------
55// Details: CMICmnLLDBDebuggerHandleEvents destructor.
56// Type: Overridable.
57// Args: None.
58// Return: None.
59// Throws: None.
60//--
61CMICmnLLDBDebuggerHandleEvents::~CMICmnLLDBDebuggerHandleEvents() {
62 Shutdown();
63}
64
65//++
66//------------------------------------------------------------------------------------
67// Details: Initialize resources for *this broadcaster object.
68// Type: Method.
69// Args: None.
70// Return: MIstatus::success - Functionality succeeded.
71// MIstatus::failure - Functionality failed.
72// Throws: None.
73//--
74bool CMICmnLLDBDebuggerHandleEvents::Initialize() {
75 m_clientUsageRefCnt++;
76
77 if (m_bInitialized)
78 return MIstatus::success;
79
80 m_bInitialized = MIstatus::success;
81 m_bSignalsInitialized = false;
82 m_SIGINT = 0;
83 m_SIGSTOP = 0;
84 m_SIGSEGV = 0;
85 m_SIGTRAP = 0;
86
87 return m_bInitialized;
88}
89
90//++
91//------------------------------------------------------------------------------------
92// Details: Release resources for *this broadcaster object.
93// Type: Method.
94// Args: None.
95// Return: MIstatus::success - Functionality succeeded.
96// MIstatus::failure - Functionality failed.
97// Throws: None.
98//--
99bool CMICmnLLDBDebuggerHandleEvents::Shutdown() {
100 if (--m_clientUsageRefCnt > 0)
101 return MIstatus::success;
102
103 if (!m_bInitialized)
104 return MIstatus::success;
105
106 m_bInitialized = false;
107
108 return MIstatus::success;
109}
110
111//++
112//------------------------------------------------------------------------------------
113// Details: Interpret the event object to ascertain the action to take or
114// information to
115// to form and put in a MI Out-of-band record object which is given to
116// stdout.
117// Type: Method.
118// Args: vEvent - (R) An LLDB broadcast event.
119// vrbHandledEvent - (W) True - event handled, false = not handled.
120// Return: MIstatus::success - Functionality succeeded.
121// MIstatus::failure - Functionality failed.
122// Throws: None.
123//--
124bool CMICmnLLDBDebuggerHandleEvents::HandleEvent(const lldb::SBEvent &vEvent,
125 bool &vrbHandledEvent) {
126 bool bOk = MIstatus::success;
127 vrbHandledEvent = false;
128
129 if (lldb::SBProcess::EventIsProcessEvent(vEvent)) {
130 vrbHandledEvent = true;
131 bOk = HandleEventSBProcess(vEvent);
132 } else if (lldb::SBBreakpoint::EventIsBreakpointEvent(vEvent)) {
133 vrbHandledEvent = true;
134 bOk = HandleEventSBBreakPoint(vEvent);
135 } else if (lldb::SBThread::EventIsThreadEvent(vEvent)) {
136 vrbHandledEvent = true;
137 bOk = HandleEventSBThread(vEvent);
138 } else if (lldb::SBTarget::EventIsTargetEvent(vEvent)) {
139 vrbHandledEvent = true;
140 bOk = HandleEventSBTarget(vEvent);
141 } else if (lldb::SBCommandInterpreter::EventIsCommandInterpreterEvent(
142 vEvent)) {
143 vrbHandledEvent = true;
144 bOk = HandleEventSBCommandInterpreter(vEvent);
145 }
146
147 return bOk;
148}
149
150//++
151//------------------------------------------------------------------------------------
152// Details: Handle a LLDB SBProcess event.
153// Type: Method.
154// Args: vEvent - (R) An LLDB broadcast event.
155// Return: MIstatus::success - Functionality succeeded.
156// MIstatus::failure - Functionality failed.
157// Throws: None.
158//--
159bool CMICmnLLDBDebuggerHandleEvents::HandleEventSBProcess(
160 const lldb::SBEvent &vEvent) {
161 bool bOk = MIstatus::success;
162
163 const char *pEventType = "";
164 const MIuint nEventType = vEvent.GetType();
165 switch (nEventType) {
166 case lldb::SBProcess::eBroadcastBitInterrupt:
167 pEventType = "eBroadcastBitInterrupt";
168 break;
169 case lldb::SBProcess::eBroadcastBitProfileData:
170 pEventType = "eBroadcastBitProfileData";
171 break;
172 case lldb::SBProcess::eBroadcastBitStructuredData:
173 pEventType = "eBroadcastBitStructuredData";
174 break;
175 case lldb::SBProcess::eBroadcastBitStateChanged:
176 pEventType = "eBroadcastBitStateChanged";
177 bOk = HandleProcessEventBroadcastBitStateChanged(vEvent);
178 break;
179 case lldb::SBProcess::eBroadcastBitSTDERR:
180 pEventType = "eBroadcastBitSTDERR";
181 bOk = GetProcessStderr();
182 break;
183 case lldb::SBProcess::eBroadcastBitSTDOUT:
184 pEventType = "eBroadcastBitSTDOUT";
185 bOk = GetProcessStdout();
186 break;
187 default: {
188 const CMIUtilString msg(
189 CMIUtilString::Format(MIRSRC(IDS_LLDBOUTOFBAND_ERR_UNKNOWN_EVENT)CMICmnResources::Instance().GetString(IDS_LLDBOUTOFBAND_ERR_UNKNOWN_EVENT
).c_str()
,
190 "SBProcess", (MIuint)nEventType));
191 SetErrorDescription(msg);
192 return MIstatus::failure;
193 }
194 }
195 m_pLog->WriteLog(CMIUtilString::Format(
196 "##### An SB Process event occurred: %s", pEventType));
197
198 return bOk;
199}
200
201//++
202//------------------------------------------------------------------------------------
203// Details: Handle a LLDB SBBreakpoint event.
204// Type: Method.
205// Args: vEvent - (R) An LLDB broadcast event.
206// Return: MIstatus::success - Functionality succeeded.
207// MIstatus::failure - Functionality failed.
208// Throws: None.
209//--
210bool CMICmnLLDBDebuggerHandleEvents::HandleEventSBBreakPoint(
211 const lldb::SBEvent &vEvent) {
212 bool bOk = MIstatus::success;
213
214 const char *pEventType = "";
215 const lldb::BreakpointEventType eEvent =
216 lldb::SBBreakpoint::GetBreakpointEventTypeFromEvent(vEvent);
217 switch (eEvent) {
218 case lldb::eBreakpointEventTypeThreadChanged:
219 pEventType = "eBreakpointEventTypeThreadChanged";
220 break;
221 case lldb::eBreakpointEventTypeLocationsRemoved:
222 pEventType = "eBreakpointEventTypeLocationsRemoved";
223 break;
224 case lldb::eBreakpointEventTypeInvalidType:
225 pEventType = "eBreakpointEventTypeInvalidType";
226 break;
227 case lldb::eBreakpointEventTypeLocationsAdded:
228 pEventType = "eBreakpointEventTypeLocationsAdded";
229 bOk = HandleEventSBBreakpointLocationsAdded(vEvent);
230 break;
231 case lldb::eBreakpointEventTypeAdded:
232 pEventType = "eBreakpointEventTypeAdded";
233 bOk = HandleEventSBBreakpointAdded(vEvent);
234 break;
235 case lldb::eBreakpointEventTypeRemoved:
236 pEventType = "eBreakpointEventTypeRemoved";
237 bOk = HandleEventSBBreakpointCmn(vEvent);
238 break;
239 case lldb::eBreakpointEventTypeLocationsResolved:
240 pEventType = "eBreakpointEventTypeLocationsResolved";
241 bOk = HandleEventSBBreakpointCmn(vEvent);
242 break;
243 case lldb::eBreakpointEventTypeEnabled:
244 pEventType = "eBreakpointEventTypeEnabled";
245 bOk = HandleEventSBBreakpointCmn(vEvent);
246 break;
247 case lldb::eBreakpointEventTypeDisabled:
248 pEventType = "eBreakpointEventTypeDisabled";
249 bOk = HandleEventSBBreakpointCmn(vEvent);
250 break;
251 case lldb::eBreakpointEventTypeCommandChanged:
252 pEventType = "eBreakpointEventTypeCommandChanged";
253 bOk = HandleEventSBBreakpointCmn(vEvent);
254 break;
255 case lldb::eBreakpointEventTypeConditionChanged:
256 pEventType = "eBreakpointEventTypeConditionChanged";
257 bOk = HandleEventSBBreakpointCmn(vEvent);
258 break;
259 case lldb::eBreakpointEventTypeIgnoreChanged:
260 pEventType = "eBreakpointEventTypeIgnoreChanged";
261 bOk = HandleEventSBBreakpointCmn(vEvent);
262 break;
263 }
264 m_pLog->WriteLog(CMIUtilString::Format(
265 "##### An SB Breakpoint event occurred: %s", pEventType));
266
267 return bOk;
268}
269
270//++
271//------------------------------------------------------------------------------------
272// Details: Handle a LLDB SBBreakpoint event.
273// Type: Method.
274// Args: vEvent - (R) An LLDB broadcast event.
275// Return: MIstatus::success - Functionality succeeded.
276// MIstatus::failure - Functionality failed.
277// Throws: None.
278//--
279bool CMICmnLLDBDebuggerHandleEvents::HandleEventSBBreakpointLocationsAdded(
280 const lldb::SBEvent &vEvent) {
281 const MIuint nLoc =
282 lldb::SBBreakpoint::GetNumBreakpointLocationsFromEvent(vEvent);
283 if (nLoc == 0)
284 return MIstatus::success;
285
286 lldb::SBBreakpoint brkPt = lldb::SBBreakpoint::GetBreakpointFromEvent(vEvent);
287 const CMIUtilString plural((nLoc == 1) ? "" : "s");
288 const CMIUtilString msg(
289 CMIUtilString::Format("%d location%s added to breakpoint %d", nLoc,
290 plural.c_str(), brkPt.GetID()));
291
292 return TextToStdout(msg);
293}
294
295//++
296//------------------------------------------------------------------------------------
297// Details: Handle a LLDB SBBreakpoint event.
298// Type: Method.
299// Args: vEvent - (R) An LLDB broadcast event.
300// Return: MIstatus::success - Functionality succeeded.
301// MIstatus::failure - Functionality failed.
302// Throws: None.
303//--
304bool CMICmnLLDBDebuggerHandleEvents::HandleEventSBBreakpointCmn(
305 const lldb::SBEvent &vEvent) {
306 lldb::SBBreakpoint brkPt = lldb::SBBreakpoint::GetBreakpointFromEvent(vEvent);
307 if (!brkPt.IsValid())
308 return MIstatus::success;
309
310 CMICmnLLDBDebugSessionInfo &rSessionInfo(
311 CMICmnLLDBDebugSessionInfo::Instance());
312 CMICmnLLDBDebugSessionInfo::SBrkPtInfo sBrkPtInfo;
313 if (!rSessionInfo.GetBrkPtInfo(brkPt, sBrkPtInfo)) {
314 SetErrorDescription(
315 CMIUtilString::Format(MIRSRC(IDS_LLDBOUTOFBAND_ERR_BRKPT_INFO_GET)CMICmnResources::Instance().GetString(IDS_LLDBOUTOFBAND_ERR_BRKPT_INFO_GET
).c_str()
,
316 "HandleEventSBBreakpointCmn()", brkPt.GetID()));
317 return MIstatus::failure;
318 }
319
320 // CODETAG_LLDB_BREAKPOINT_CREATION
321 // This is in a worker thread
322 // Add more breakpoint information or overwrite existing information
323 CMICmnLLDBDebugSessionInfo::SBrkPtInfo sBrkPtInfoRec;
324 if (!rSessionInfo.RecordBrkPtInfoGet(brkPt.GetID(), sBrkPtInfoRec)) {
325 SetErrorDescription(
326 CMIUtilString::Format(MIRSRC(IDS_LLDBOUTOFBAND_ERR_BRKPT_NOTFOUND)CMICmnResources::Instance().GetString(IDS_LLDBOUTOFBAND_ERR_BRKPT_NOTFOUND
).c_str()
,
327 "HandleEventSBBreakpointCmn()", brkPt.GetID()));
328 return MIstatus::failure;
329 }
330 sBrkPtInfo.m_bDisp = sBrkPtInfoRec.m_bDisp;
331 sBrkPtInfo.m_bEnabled = brkPt.IsEnabled();
332 sBrkPtInfo.m_bHaveArgOptionThreadGrp = false;
333 sBrkPtInfo.m_strOptThrdGrp = "";
334 sBrkPtInfo.m_nTimes = brkPt.GetHitCount();
335 sBrkPtInfo.m_strOrigLoc = sBrkPtInfoRec.m_strOrigLoc;
336 sBrkPtInfo.m_nIgnore = sBrkPtInfoRec.m_nIgnore;
337 sBrkPtInfo.m_bPending = sBrkPtInfoRec.m_bPending;
338 sBrkPtInfo.m_bCondition = sBrkPtInfoRec.m_bCondition;
339 sBrkPtInfo.m_strCondition = sBrkPtInfoRec.m_strCondition;
340 sBrkPtInfo.m_bBrkPtThreadId = sBrkPtInfoRec.m_bBrkPtThreadId;
341 sBrkPtInfo.m_nBrkPtThreadId = sBrkPtInfoRec.m_nBrkPtThreadId;
342
343 // MI print
344 // "=breakpoint-modified,bkpt={number=\"%d\",type=\"breakpoint\",disp=\"%s\",enabled=\"%c\",addr=\"0x%016"
345 // PRIx64 "\",
346 // func=\"%s\",file=\"%s\",fullname=\"%s/%s\",line=\"%d\",times=\"%d\",original-location=\"%s\"}"
347 CMICmnMIValueTuple miValueTuple;
348 if (!rSessionInfo.MIResponseFormBrkPtInfo(sBrkPtInfo, miValueTuple)) {
349 SetErrorDescription(
350 CMIUtilString::Format(MIRSRC(IDS_LLDBOUTOFBAND_ERR_FORM_MI_RESPONSE)CMICmnResources::Instance().GetString(IDS_LLDBOUTOFBAND_ERR_FORM_MI_RESPONSE
).c_str()
,
351 "HandleEventSBBreakpointCmn()"));
352 return MIstatus::failure;
353 }
354
355 const CMICmnMIValueResult miValueResultC("bkpt", miValueTuple);
356 const CMICmnMIOutOfBandRecord miOutOfBandRecord(
357 CMICmnMIOutOfBandRecord::eOutOfBand_BreakPointModified, miValueResultC);
358 bool bOk = MiOutOfBandRecordToStdout(miOutOfBandRecord);
359 bOk = bOk && CMICmnStreamStdout::WritePrompt();
360
361 return bOk;
362}
363
364//++
365//------------------------------------------------------------------------------------
366// Details: Handle a LLDB SBBreakpoint added event.
367// Add more breakpoint information or overwrite existing information.
368// Normally a break point session info objects exists by now when an MI
369// command
370// was issued to insert a break so the retrieval would normally always
371// succeed
372// however should a user type "b main" into a console then LLDB will
373// create a
374// breakpoint directly, hence no MI command, hence no previous record
375// of the
376// breakpoint so RecordBrkPtInfoGet() will fail. We still get the event
377// though
378// so need to create a breakpoint info object here and send appropriate
379// MI
380// response.
381// Type: Method.
382// Args: vEvent - (R) An LLDB broadcast event.
383// Return: MIstatus::success - Functionality succeeded.
384// MIstatus::failure - Functionality failed.
385// Throws: None.
386//--
387bool CMICmnLLDBDebuggerHandleEvents::HandleEventSBBreakpointAdded(
388 const lldb::SBEvent &vEvent) {
389 lldb::SBBreakpoint brkPt = lldb::SBBreakpoint::GetBreakpointFromEvent(vEvent);
390 if (!brkPt.IsValid())
391 return MIstatus::success;
392
393 CMICmnLLDBDebugSessionInfo &rSessionInfo(
394 CMICmnLLDBDebugSessionInfo::Instance());
395 CMICmnLLDBDebugSessionInfo::SBrkPtInfo sBrkPtInfo;
396 if (!rSessionInfo.GetBrkPtInfo(brkPt, sBrkPtInfo)) {
397 SetErrorDescription(
398 CMIUtilString::Format(MIRSRC(IDS_LLDBOUTOFBAND_ERR_BRKPT_INFO_GET)CMICmnResources::Instance().GetString(IDS_LLDBOUTOFBAND_ERR_BRKPT_INFO_GET
).c_str()
,
399 "HandleEventSBBreakpointAdded()", brkPt.GetID()));
400 return MIstatus::failure;
401 }
402
403 // CODETAG_LLDB_BREAKPOINT_CREATION
404 // This is in a worker thread
405 CMICmnLLDBDebugSessionInfo::SBrkPtInfo sBrkPtInfoRec;
406 const bool bBrkPtExistAlready =
407 rSessionInfo.RecordBrkPtInfoGet(brkPt.GetID(), sBrkPtInfoRec);
408 if (bBrkPtExistAlready) {
409 // Update breakpoint information object
410 sBrkPtInfo.m_bDisp = sBrkPtInfoRec.m_bDisp;
411 sBrkPtInfo.m_bEnabled = brkPt.IsEnabled();
412 sBrkPtInfo.m_bHaveArgOptionThreadGrp = false;
413 sBrkPtInfo.m_strOptThrdGrp.clear();
414 sBrkPtInfo.m_nTimes = brkPt.GetHitCount();
415 sBrkPtInfo.m_strOrigLoc = sBrkPtInfoRec.m_strOrigLoc;
416 sBrkPtInfo.m_nIgnore = sBrkPtInfoRec.m_nIgnore;
417 sBrkPtInfo.m_bPending = sBrkPtInfoRec.m_bPending;
418 sBrkPtInfo.m_bCondition = sBrkPtInfoRec.m_bCondition;
419 sBrkPtInfo.m_strCondition = sBrkPtInfoRec.m_strCondition;
420 sBrkPtInfo.m_bBrkPtThreadId = sBrkPtInfoRec.m_bBrkPtThreadId;
421 sBrkPtInfo.m_nBrkPtThreadId = sBrkPtInfoRec.m_nBrkPtThreadId;
422 } else {
423 // Create a breakpoint information object
424 sBrkPtInfo.m_bDisp = brkPt.IsOneShot();
425 sBrkPtInfo.m_bEnabled = brkPt.IsEnabled();
426 sBrkPtInfo.m_bHaveArgOptionThreadGrp = false;
427 sBrkPtInfo.m_strOptThrdGrp.clear();
428 sBrkPtInfo.m_strOrigLoc = CMIUtilString::Format(
429 "%s:%d", sBrkPtInfo.m_fileName.c_str(), sBrkPtInfo.m_nLine);
430 sBrkPtInfo.m_nIgnore = brkPt.GetIgnoreCount();
431 sBrkPtInfo.m_bPending = false;
432 const char *pStrCondition = brkPt.GetCondition();
433 sBrkPtInfo.m_bCondition = (pStrCondition != nullptr) ? true : false;
434 sBrkPtInfo.m_strCondition =
435 (pStrCondition != nullptr) ? pStrCondition : "??";
436 sBrkPtInfo.m_bBrkPtThreadId = (brkPt.GetThreadID() != 0) ? true : false;
437 sBrkPtInfo.m_nBrkPtThreadId = brkPt.GetThreadID();
438 }
439
440 CMICmnMIValueTuple miValueTuple;
441 if (!rSessionInfo.MIResponseFormBrkPtInfo(sBrkPtInfo, miValueTuple)) {
442 SetErrorDescription(
443 CMIUtilString::Format(MIRSRC(IDS_LLDBOUTOFBAND_ERR_FORM_MI_RESPONSE)CMICmnResources::Instance().GetString(IDS_LLDBOUTOFBAND_ERR_FORM_MI_RESPONSE
).c_str()
,
444 "HandleEventSBBreakpointAdded()"));
445 return MIstatus::failure;
446 }
447
448 bool bOk = MIstatus::success;
449 if (bBrkPtExistAlready) {
450 // MI print
451 // "=breakpoint-modified,bkpt={number=\"%d\",type=\"breakpoint\",disp=\"%s\",enabled=\"%c\",addr=\"0x%016"
452 // PRIx64
453 // "\",func=\"%s\",file=\"%s\",fullname=\"%s/%s\",line=\"%d\",times=\"%d\",original-location=\"%s\"}"
454 const CMICmnMIValueResult miValueResult("bkpt", miValueTuple);
455 const CMICmnMIOutOfBandRecord miOutOfBandRecord(
456 CMICmnMIOutOfBandRecord::eOutOfBand_BreakPointModified, miValueResult);
457 bOk = MiOutOfBandRecordToStdout(miOutOfBandRecord);
458 bOk = bOk && CMICmnStreamStdout::WritePrompt();
459 } else {
460 // CODETAG_LLDB_BRKPT_ID_MAX
461 if (brkPt.GetID() > (lldb::break_id_t)rSessionInfo.m_nBrkPointCntMax) {
462 SetErrorDescription(CMIUtilString::Format(
463 MIRSRC(IDS_CMD_ERR_BRKPT_CNT_EXCEEDED)CMICmnResources::Instance().GetString(IDS_CMD_ERR_BRKPT_CNT_EXCEEDED
).c_str()
,
464 "HandleEventSBBreakpointAdded()", rSessionInfo.m_nBrkPointCntMax,
465 sBrkPtInfo.m_id));
466 return MIstatus::failure;
467 }
468 if (!rSessionInfo.RecordBrkPtInfo(brkPt.GetID(), sBrkPtInfo)) {
469 SetErrorDescription(CMIUtilString::Format(
470 MIRSRC(IDS_LLDBOUTOFBAND_ERR_BRKPT_INFO_SET)CMICmnResources::Instance().GetString(IDS_LLDBOUTOFBAND_ERR_BRKPT_INFO_SET
).c_str()
,
471 "HandleEventSBBreakpointAdded()", sBrkPtInfo.m_id));
472 return MIstatus::failure;
473 }
474
475 // MI print
476 // "=breakpoint-created,bkpt={number=\"%d\",type=\"breakpoint\",disp=\"%s\",enabled=\"%c\",addr=\"0x%016"
477 // PRIx64
478 // "\",func=\"%s\",file=\"%s\",fullname=\"%s/%s\",line=\"%d\",times=\"%d\",original-location=\"%s\"}"
479 const CMICmnMIValueResult miValueResult("bkpt", miValueTuple);
480 const CMICmnMIOutOfBandRecord miOutOfBandRecord(
481 CMICmnMIOutOfBandRecord::eOutOfBand_BreakPointCreated, miValueResult);
482 bOk = MiOutOfBandRecordToStdout(miOutOfBandRecord);
483 bOk = bOk && CMICmnStreamStdout::WritePrompt();
484 }
485
486 return bOk;
487}
488
489//++
490//------------------------------------------------------------------------------------
491// Details: Handle a LLDB SBThread event.
492// Type: Method.
493// Args: vEvent - (R) An LLDB broadcast event.
494// Return: MIstatus::success - Functionality succeeded.
495// MIstatus::failure - Functionality failed.
496// Throws: None.
497//--
498bool CMICmnLLDBDebuggerHandleEvents::HandleEventSBThread(
499 const lldb::SBEvent &vEvent) {
500 if (!ChkForStateChanges())
501 return MIstatus::failure;
502
503 bool bOk = MIstatus::success;
504 const char *pEventType = "";
505 const MIuint nEventType = vEvent.GetType();
506 switch (nEventType) {
507 case lldb::SBThread::eBroadcastBitStackChanged:
508 pEventType = "eBroadcastBitStackChanged";
509 bOk = HandleEventSBThreadBitStackChanged(vEvent);
510 break;
511 case lldb::SBThread::eBroadcastBitThreadSuspended:
512 pEventType = "eBroadcastBitThreadSuspended";
513 bOk = HandleEventSBThreadSuspended(vEvent);
514 break;
515 case lldb::SBThread::eBroadcastBitThreadResumed:
516 pEventType = "eBroadcastBitThreadResumed";
517 break;
518 case lldb::SBThread::eBroadcastBitSelectedFrameChanged:
519 pEventType = "eBroadcastBitSelectedFrameChanged";
520 break;
521 case lldb::SBThread::eBroadcastBitThreadSelected:
522 pEventType = "eBroadcastBitThreadSelected";
523 break;
524 default: {
525 const CMIUtilString msg(
526 CMIUtilString::Format(MIRSRC(IDS_LLDBOUTOFBAND_ERR_UNKNOWN_EVENT)CMICmnResources::Instance().GetString(IDS_LLDBOUTOFBAND_ERR_UNKNOWN_EVENT
).c_str()
,
527 "SBThread", (MIuint)nEventType));
528 SetErrorDescription(msg);
529 return MIstatus::failure;
530 }
531 }
532 m_pLog->WriteLog(CMIUtilString::Format("##### An SBThread event occurred: %s",
533 pEventType));
534
535 return bOk;
536}
537
538//++
539//------------------------------------------------------------------------------------
540// Details: Handle a LLDB SBThread event.
541// Type: Method.
542// Args: vEvent - (R) An LLDB broadcast event.
543// Return: MIstatus::success - Functionality succeeded.
544// MIstatus::failure - Functionality failed.
545// Throws: None.
546//--
547bool CMICmnLLDBDebuggerHandleEvents::HandleEventSBThreadSuspended(
548 const lldb::SBEvent &vEvent) {
549 lldb::SBThread thread = lldb::SBThread::GetThreadFromEvent(vEvent);
550 if (!thread.IsValid())
551 return MIstatus::success;
552
553 const lldb::StopReason eStopReason = thread.GetStopReason();
554 if (eStopReason != lldb::eStopReasonSignal)
555 return MIstatus::success;
556
557 // MI print "@thread=%d,signal=%lld"
558 const MIuint64 nId = thread.GetStopReasonDataAtIndex(0);
559 const CMIUtilString strThread(
560 CMIUtilString::Format("%d", thread.GetThreadID()));
561 const CMICmnMIValueConst miValueConst(strThread);
562 const CMICmnMIValueResult miValueResult("thread", miValueConst);
563 CMICmnMIOutOfBandRecord miOutOfBandRecord(
564 CMICmnMIOutOfBandRecord::eOutOfBand_Thread, miValueResult);
565 const CMIUtilString strSignal(CMIUtilString::Format("%lld", nId));
566 const CMICmnMIValueConst miValueConst2(strSignal);
567 const CMICmnMIValueResult miValueResult2("signal", miValueConst2);
568 miOutOfBandRecord.Add(miValueResult2);
569 return MiOutOfBandRecordToStdout(miOutOfBandRecord);
570}
571
572//++
573//------------------------------------------------------------------------------------
574// Details: Handle a LLDB SBThread event.
575// Type: Method.
576// Args: vEvent - (R) An LLDB broadcast event.
577// Return: MIstatus::success - Functionality succeeded.
578// MIstatus::failure - Functionality failed.
579// Throws: None.
580//--
581bool CMICmnLLDBDebuggerHandleEvents::HandleEventSBThreadBitStackChanged(
582 const lldb::SBEvent &vEvent) {
583 lldb::SBThread thread = lldb::SBThread::GetThreadFromEvent(vEvent);
584 if (!thread.IsValid())
585 return MIstatus::success;
586
587 lldb::SBStream streamOut;
588 const bool bOk = thread.GetStatus(streamOut);
589 return bOk && TextToStdout(streamOut.GetData());
590}
591
592//++
593//------------------------------------------------------------------------------------
594// Details: Handle a LLDB SBTarget event.
595// Type: Method.
596// Args: vEvent - (R) An LLDB broadcast event.
597// Return: MIstatus::success - Functional succeeded.
598// MIstatus::failure - Functional failed.
599// Throws: None.
600//--
601bool CMICmnLLDBDebuggerHandleEvents::HandleEventSBTarget(
602 const lldb::SBEvent &vEvent) {
603 if (!ChkForStateChanges())
604 return MIstatus::failure;
605
606 bool bOk = MIstatus::success;
607 const char *pEventType = "";
608 const MIuint nEventType = vEvent.GetType();
609 switch (nEventType) {
610 case lldb::SBTarget::eBroadcastBitBreakpointChanged:
611 pEventType = "eBroadcastBitBreakpointChanged";
612 break;
613 case lldb::SBTarget::eBroadcastBitModulesLoaded:
614 pEventType = "eBroadcastBitModulesLoaded";
615 bOk = HandleTargetEventBroadcastBitModulesLoaded(vEvent);
616 break;
617 case lldb::SBTarget::eBroadcastBitModulesUnloaded:
618 pEventType = "eBroadcastBitModulesUnloaded";
619 bOk = HandleTargetEventBroadcastBitModulesUnloaded(vEvent);
620 break;
621 case lldb::SBTarget::eBroadcastBitWatchpointChanged:
622 pEventType = "eBroadcastBitWatchpointChanged";
623 break;
624 case lldb::SBTarget::eBroadcastBitSymbolsLoaded:
625 pEventType = "eBroadcastBitSymbolsLoaded";
626 break;
627 default: {
628 const CMIUtilString msg(
629 CMIUtilString::Format(MIRSRC(IDS_LLDBOUTOFBAND_ERR_UNKNOWN_EVENT)CMICmnResources::Instance().GetString(IDS_LLDBOUTOFBAND_ERR_UNKNOWN_EVENT
).c_str()
,
630 "SBTarget", (MIuint)nEventType));
631 SetErrorDescription(msg);
632 return MIstatus::failure;
633 }
634 }
635 m_pLog->WriteLog(CMIUtilString::Format("##### An SBTarget event occurred: %s",
636 pEventType));
637
638 return bOk;
639}
640
641//++
642//------------------------------------------------------------------------------------
643// Details: Print to stdout
644// "=library-loaded,id=\"%s\",target-name=\"%s\",host-name=\"%s\",symbols-loaded="%d"[,symbols-path=\"%s\"],loaded_addr=\"0x%016"
645// PRIx64"\""
646// Type: Method.
647// Args: None.
648// Return: MIstatus::success - Function succeeded.
649// MIstatus::failure - Function failed.
650// Throws: None.
651//--
652bool CMICmnLLDBDebuggerHandleEvents::HandleTargetEventBroadcastBitModulesLoaded(
653 const lldb::SBEvent &vEvent) {
654 bool bOk = MIstatus::failure;
655 const MIuint nSize = lldb::SBTarget::GetNumModulesFromEvent(vEvent);
656 for (MIuint nIndex = 0; nIndex < nSize; ++nIndex) {
657 const lldb::SBModule sbModule =
658 lldb::SBTarget::GetModuleAtIndexFromEvent(nIndex, vEvent);
659 CMICmnMIOutOfBandRecord miOutOfBandRecord(
660 CMICmnMIOutOfBandRecord::eOutOfBand_TargetModuleLoaded);
661 const bool bWithExtraFields = true;
662 bOk = MiHelpGetModuleInfo(sbModule, bWithExtraFields, miOutOfBandRecord);
663 bOk = bOk && MiOutOfBandRecordToStdout(miOutOfBandRecord);
664 if (!bOk)
665 break;
666 }
667
668 return bOk;
669}
670
671//++
672//------------------------------------------------------------------------------------
673// Details: Print to stdout
674// "=library-unloaded,id=\"%s\",target-name=\"%s\",host-name=\"%s\",symbols-loaded="%d"[,symbols-path=\"%s\"],loaded_addr=\"0x%016"
675// PRIx64"\""
676// Type: Method.
677// Args: None.
678// Return: MIstatus::success - Function succeeded.
679// MIstatus::failure - Function failed.
680// Throws: None.
681//--
682bool CMICmnLLDBDebuggerHandleEvents::
683 HandleTargetEventBroadcastBitModulesUnloaded(const lldb::SBEvent &vEvent) {
684 bool bOk = MIstatus::failure;
685 const MIuint nSize = lldb::SBTarget::GetNumModulesFromEvent(vEvent);
686 for (MIuint nIndex = 0; nIndex < nSize; ++nIndex) {
687 const lldb::SBModule sbModule =
688 lldb::SBTarget::GetModuleAtIndexFromEvent(nIndex, vEvent);
689 CMICmnMIOutOfBandRecord miOutOfBandRecord(
690 CMICmnMIOutOfBandRecord::eOutOfBand_TargetModuleUnloaded);
691 const bool bWithExtraFields = false;
692 bOk = MiHelpGetModuleInfo(sbModule, bWithExtraFields, miOutOfBandRecord);
693 bOk = bOk && MiOutOfBandRecordToStdout(miOutOfBandRecord);
694 if (!bOk)
695 break;
696 }
697
698 return bOk;
699}
700
701//++
702//------------------------------------------------------------------------------------
703// Details: Build module information for =library-loaded/=library-unloaded:
704// "id=\"%s\",target-name=\"%s\",host-name=\"%s\",symbols-loaded="%d"[,symbols-path=\"%s\"],loaded_addr=\"0x%016"
705// PRIx64"\""
706// Type: Method.
707// Args: vwrMiValueList - (W) MI value list object.
708// Return: MIstatus::success - Function succeeded.
709// MIstatus::failure - Function failed.
710// Throws: None.
711//--
712bool CMICmnLLDBDebuggerHandleEvents::MiHelpGetModuleInfo(
713 const lldb::SBModule &vModule, const bool vbWithExtraFields,
714 CMICmnMIOutOfBandRecord &vwrMiOutOfBandRecord) {
715 bool bOk = MIstatus::success;
716
717 // First, build standard fields:
718 // Build "id" field
719 std::unique_ptr<char[]> apPath(new char[PATH_MAX4096]);
720 vModule.GetFileSpec().GetPath(apPath.get(), PATH_MAX4096);
721 const CMIUtilString strTargetPath(apPath.get());
722 const CMICmnMIValueConst miValueConst(strTargetPath.AddSlashes());
723 const CMICmnMIValueResult miValueResult("id", miValueConst);
724 vwrMiOutOfBandRecord.Add(miValueResult);
725 // Build "target-name" field
726 const CMICmnMIValueConst miValueConst2(strTargetPath.AddSlashes());
727 const CMICmnMIValueResult miValueResult2("target-name", miValueConst2);
728 vwrMiOutOfBandRecord.Add(miValueResult2);
729 // Build "host-name" field
730 vModule.GetPlatformFileSpec().GetPath(apPath.get(), PATH_MAX4096);
731 const CMIUtilString strHostPath(apPath.get());
732 const CMICmnMIValueConst miValueConst3(strHostPath.AddSlashes());
733 const CMICmnMIValueResult miValueResult3("host-name", miValueConst3);
734 vwrMiOutOfBandRecord.Add(miValueResult3);
735
736 // Then build extra fields if needed:
737 if (vbWithExtraFields) {
738 // Build "symbols-loaded" field
739 vModule.GetSymbolFileSpec().GetPath(apPath.get(), PATH_MAX4096);
740 const CMIUtilString strSymbolsPath(apPath.get());
741 const bool bSymbolsLoaded =
742 !CMIUtilString::Compare(strHostPath, strSymbolsPath);
743 const CMICmnMIValueConst miValueConst4(
744 CMIUtilString::Format("%d", bSymbolsLoaded));
745 const CMICmnMIValueResult miValueResult4("symbols-loaded", miValueConst4);
746 vwrMiOutOfBandRecord.Add(miValueResult4);
747 // Build "symbols-path" field
748 if (bSymbolsLoaded) {
749 const CMICmnMIValueConst miValueConst5(strSymbolsPath.AddSlashes());
750 const CMICmnMIValueResult miValueResult5("symbols-path", miValueConst5);
751 vwrMiOutOfBandRecord.Add(miValueResult5);
752 }
753 // Build "loaded_addr" field
754 lldb::SBAddress sbAddress(vModule.GetObjectFileHeaderAddress());
755 CMICmnLLDBDebugSessionInfo &rSessionInfo(
756 CMICmnLLDBDebugSessionInfo::Instance());
757 const lldb::addr_t nLoadAddress(
758 sbAddress.GetLoadAddress(rSessionInfo.GetTarget()));
759 const CMIUtilString strLoadedAddr(
760 nLoadAddress != LLDB_INVALID_ADDRESS(18446744073709551615UL)
761 ? CMIUtilString::Format("0x%016" PRIx64"l" "x", nLoadAddress)
762 : "-");
763 const CMICmnMIValueConst miValueConst6(strLoadedAddr);
764 const CMICmnMIValueResult miValueResult6("loaded_addr", miValueConst6);
765 vwrMiOutOfBandRecord.Add(miValueResult6);
766
767 // Build "size" field
768 lldb::SBSection sbSection = sbAddress.GetSection();
769 const CMIUtilString strSize(
770 CMIUtilString::Format("%" PRIu64"l" "u", sbSection.GetByteSize()));
771 const CMICmnMIValueConst miValueConst7(strSize);
772 const CMICmnMIValueResult miValueResult7("size", miValueConst7);
773 vwrMiOutOfBandRecord.Add(miValueResult7);
774 }
775
776 return bOk;
777}
778
779//++
780//------------------------------------------------------------------------------------
781// Details: Handle a LLDB SBCommandInterpreter event.
782// Type: Method.
783// Args: vEvent - (R) An LLDB command interpreter event.
784// Return: MIstatus::success - Functionality succeeded.
785// MIstatus::failure - Functionality failed.
786// Throws: None.
787//--
788bool CMICmnLLDBDebuggerHandleEvents::HandleEventSBCommandInterpreter(
789 const lldb::SBEvent &vEvent) {
790 // This function is not used
791 // *** This function is under development
792
793 const char *pEventType = "";
794 const MIuint nEventType = vEvent.GetType();
795 switch (nEventType) {
796 case lldb::SBCommandInterpreter::eBroadcastBitThreadShouldExit:
797 pEventType = "eBroadcastBitThreadShouldExit";
798 // ToDo: IOR: Reminder to maybe handle this here
799 // const MIuint nEventType = event.GetType();
800 // if (nEventType &
801 // lldb::SBCommandInterpreter::eBroadcastBitThreadShouldExit)
802 //{
803 // m_pClientDriver->SetExitApplicationFlag();
804 // vrbYesExit = true;
805 // return MIstatus::success;
806 //}
807 break;
808 case lldb::SBCommandInterpreter::eBroadcastBitResetPrompt:
809 pEventType = "eBroadcastBitResetPrompt";
810 break;
811 case lldb::SBCommandInterpreter::eBroadcastBitQuitCommandReceived: {
812 pEventType = "eBroadcastBitQuitCommandReceived";
813 const bool bForceExit = true;
814 CMICmnLLDBDebugger::Instance().GetDriver().SetExitApplicationFlag(
815 bForceExit);
816 break;
817 }
818 case lldb::SBCommandInterpreter::eBroadcastBitAsynchronousOutputData:
819 pEventType = "eBroadcastBitAsynchronousOutputData";
820 break;
821 case lldb::SBCommandInterpreter::eBroadcastBitAsynchronousErrorData:
822 pEventType = "eBroadcastBitAsynchronousErrorData";
823 break;
824 default: {
825 const CMIUtilString msg(
826 CMIUtilString::Format(MIRSRC(IDS_LLDBOUTOFBAND_ERR_UNKNOWN_EVENT)CMICmnResources::Instance().GetString(IDS_LLDBOUTOFBAND_ERR_UNKNOWN_EVENT
).c_str()
,
827 "SBCommandInterpreter", (MIuint)nEventType));
828 SetErrorDescription(msg);
829 return MIstatus::failure;
830 }
831 }
832 m_pLog->WriteLog(CMIUtilString::Format(
833 "##### An SBCommandInterpreter event occurred: %s", pEventType));
834
835 return MIstatus::success;
836}
837
838//++
839//------------------------------------------------------------------------------------
840// Details: Handle SBProcess event eBroadcastBitStateChanged.
841// Type: Method.
842// Args: vEvent - (R) An LLDB event object.
843// Return: MIstatus::success - Functionality succeeded.
844// MIstatus::failure - Functionality failed.
845// Throws: None.
846//--
847bool CMICmnLLDBDebuggerHandleEvents::HandleProcessEventBroadcastBitStateChanged(
848 const lldb::SBEvent &vEvent) {
849 // Make sure the program hasn't been auto-restarted:
850 if (lldb::SBProcess::GetRestartedFromEvent(vEvent))
851 return MIstatus::success;
852
853 bool bOk = ChkForStateChanges();
854 bOk = bOk && GetProcessStdout();
855 bOk = bOk && GetProcessStderr();
856 if (!bOk)
857 return MIstatus::failure;
858
859 // Something changed in the process; get the event and report the process's
860 // current
861 // status and location
862 const lldb::StateType eEventState =
863 lldb::SBProcess::GetStateFromEvent(vEvent);
864 if (eEventState == lldb::eStateInvalid)
865 return MIstatus::success;
866
867 lldb::SBProcess process = lldb::SBProcess::GetProcessFromEvent(vEvent);
868 if (!process.IsValid()) {
869 const CMIUtilString msg(CMIUtilString::Format(
870 MIRSRC(IDS_LLDBOUTOFBAND_ERR_PROCESS_INVALID)CMICmnResources::Instance().GetString(IDS_LLDBOUTOFBAND_ERR_PROCESS_INVALID
).c_str()
, "SBProcess",
871 "HandleProcessEventBroadcastBitStateChanged()"));
872 SetErrorDescription(msg);
873 return MIstatus::failure;
874 }
875
876 bool bShouldBrk = true;
877 const char *pEventType = "";
878 switch (eEventState) {
879 case lldb::eStateUnloaded:
880 pEventType = "eStateUnloaded";
881 break;
882 case lldb::eStateConnected:
883 pEventType = "eStateConnected";
884 break;
885 case lldb::eStateAttaching:
886 pEventType = "eStateAttaching";
887 break;
888 case lldb::eStateLaunching:
889 pEventType = "eStateLaunching";
890 break;
891 case lldb::eStateStopped:
892 pEventType = "eStateStopped";
893 bOk = HandleProcessEventStateStopped(vEvent, bShouldBrk);
894 if (bShouldBrk)
895 break;
896 case lldb::eStateCrashed:
897 case lldb::eStateSuspended:
898 pEventType = "eStateSuspended";
899 bOk = HandleProcessEventStateSuspended(vEvent);
900 break;
901 case lldb::eStateRunning:
902 pEventType = "eStateRunning";
903 bOk = HandleProcessEventStateRunning();
904 break;
905 case lldb::eStateStepping:
906 pEventType = "eStateStepping";
907 break;
908 case lldb::eStateDetached:
909 pEventType = "eStateDetached";
910 break;
911 case lldb::eStateExited:
912 // Don't exit from lldb-mi here. We should be able to re-run target.
913 pEventType = "eStateExited";
914 bOk = HandleProcessEventStateExited();
915 break;
916 default: {
917 const CMIUtilString msg(CMIUtilString::Format(
918 MIRSRC(IDS_LLDBOUTOFBAND_ERR_UNKNOWN_EVENT)CMICmnResources::Instance().GetString(IDS_LLDBOUTOFBAND_ERR_UNKNOWN_EVENT
).c_str()
,
919 "SBProcess BroadcastBitStateChanged", (MIuint)eEventState));
920 SetErrorDescription(msg);
921 return MIstatus::failure;
922 }
923 }
924
925 // ToDo: Remove when finished coding application
926 m_pLog->WriteLog(CMIUtilString::Format(
927 "##### An SB Process event BroadcastBitStateChanged occurred: %s",
928 pEventType));
929
930 return bOk;
931}
932
933//++
934//------------------------------------------------------------------------------------
935// Details: Asynchronous event handler for LLDB Process state suspended.
936// Type: Method.
937// Args: vEvent - (R) An LLDB event object.
938// Return: MIstatus::success - Functionality succeeded.
939// MIstatus::failure - Functionality failed.
940// Throws: None.
941//--
942bool CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStateSuspended(
943 const lldb::SBEvent &vEvent) {
944 bool bOk = MIstatus::success;
945 lldb::SBDebugger &rDebugger =
946 CMICmnLLDBDebugSessionInfo::Instance().GetDebugger();
947 lldb::SBProcess sbProcess =
948 CMICmnLLDBDebugSessionInfo::Instance().GetProcess();
949 lldb::SBTarget target = sbProcess.GetTarget();
950 if (rDebugger.GetSelectedTarget() == target) {
951 if (!UpdateSelectedThread())
952 return MIstatus::failure;
953
954 lldb::SBCommandReturnObject result;
955 const lldb::ReturnStatus status =
956 rDebugger.GetCommandInterpreter().HandleCommand("process status",
957 result, false);
958 MIunused(status)(void)status;;
959 bOk = TextToStderr(result.GetError());
960 bOk = bOk && TextToStdout(result.GetOutput());
961 } else {
962 lldb::SBStream streamOut;
963 const MIuint nTargetIndex = rDebugger.GetIndexOfTarget(target);
964 if (nTargetIndex != UINT_MAX(2147483647 *2U +1U))
965 streamOut.Printf("Target %d: (", nTargetIndex);
966 else
967 streamOut.Printf("Target <unknown index>: (");
968 target.GetDescription(streamOut, lldb::eDescriptionLevelBrief);
969 streamOut.Printf(") stopped.\n");
970 bOk = TextToStdout(streamOut.GetData());
971 }
972
973 return bOk;
974}
975
976//++
977//------------------------------------------------------------------------------------
978// Details: Print to stdout MI formatted text to indicate process stopped.
979// Type: Method.
980// Args: vwrbShouldBrk - (W) True = Yes break, false = do not.
981// Return: MIstatus::success - Functionality succeeded.
982// MIstatus::failure - Functionality failed.
983// Throws: None.
984//--
985bool CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStateStopped(
986 const lldb::SBEvent &vrEvent, bool &vwrbShouldBrk) {
987 if (!UpdateSelectedThread())
988 return MIstatus::failure;
989
990 const char *pEventType = "";
991 bool bOk = MIstatus::success;
992 lldb::SBProcess sbProcess =
993 CMICmnLLDBDebugSessionInfo::Instance().GetProcess();
994 const lldb::StopReason eStoppedReason =
995 sbProcess.GetSelectedThread().GetStopReason();
996 switch (eStoppedReason) {
997 case lldb::eStopReasonInvalid:
998 pEventType = "eStopReasonInvalid";
999 vwrbShouldBrk = false;
1000 break;
1001 case lldb::eStopReasonNone:
1002 pEventType = "eStopReasonNone";
1003 break;
1004 case lldb::eStopReasonTrace:
1005 pEventType = "eStopReasonTrace";
1006 bOk = HandleProcessEventStopReasonTrace();
1007 break;
1008 case lldb::eStopReasonBreakpoint:
1009 pEventType = "eStopReasonBreakpoint";
1010 bOk = HandleProcessEventStopReasonBreakpoint();
1011 break;
1012 case lldb::eStopReasonWatchpoint:
1013 pEventType = "eStopReasonWatchpoint";
1014 break;
1015 case lldb::eStopReasonSignal:
1016 pEventType = "eStopReasonSignal";
1017 bOk = HandleProcessEventStopSignal(vrEvent);
1018 break;
1019 case lldb::eStopReasonException:
1020 pEventType = "eStopReasonException";
1021 bOk = HandleProcessEventStopException();
1022 break;
1023 case lldb::eStopReasonExec:
1024 pEventType = "eStopReasonExec";
1025 break;
1026 case lldb::eStopReasonPlanComplete:
1027 pEventType = "eStopReasonPlanComplete";
1028 bOk = HandleProcessEventStopReasonTrace();
1029 break;
1030 case lldb::eStopReasonThreadExiting:
1031 pEventType = "eStopReasonThreadExiting";
1032 break;
1033 case lldb::eStopReasonInstrumentation:
1034 pEventType = "eStopReasonInstrumentation";
1035 break;
1036 }
1037
1038 // ToDo: Remove when finished coding application
1039 m_pLog->WriteLog(CMIUtilString::Format(
1040 "##### An SB Process event stop state occurred: %s", pEventType));
1041
1042 return bOk;
1043}
1044
1045//++
1046//------------------------------------------------------------------------------------
1047// Details: Asynchronous event handler for LLDB Process stop signal.
1048// Type: Method.
1049// Args: vrEvent - (R) An LLDB broadcast event.
1050// Return: MIstatus::success - Functionality succeeded.
1051// MIstatus::failure - Functionality failed.
1052// Throws: None.
1053//--
1054bool CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStopSignal(
1055 const lldb::SBEvent &vrEvent) {
1056 bool bOk = MIstatus::success;
1057
1058 InitializeSignals();
1059 lldb::SBProcess sbProcess =
1060 CMICmnLLDBDebugSessionInfo::Instance().GetProcess();
1061 const MIuint64 nStopReason =
1062 sbProcess.GetSelectedThread().GetStopReasonDataAtIndex(0);
1063 const bool bInterrupted = lldb::SBProcess::GetInterruptedFromEvent(vrEvent);
1064 if (nStopReason == m_SIGINT || (nStopReason == m_SIGSTOP && bInterrupted)) {
1065 // MI print
1066 // "*stopped,reason=\"signal-received\",signal-name=\"SIGINT\",signal-meaning=\"Interrupt\",frame={%s},thread-id=\"%d\",stopped-threads=\"all\""
1067 const CMICmnMIValueConst miValueConst("signal-received");
1068 const CMICmnMIValueResult miValueResult("reason", miValueConst);
1069 CMICmnMIOutOfBandRecord miOutOfBandRecord(
1070 CMICmnMIOutOfBandRecord::eOutOfBand_Stopped, miValueResult);
1071 const CMICmnMIValueConst miValueConst2("SIGINT");
1072 const CMICmnMIValueResult miValueResult2("signal-name", miValueConst2);
1073 miOutOfBandRecord.Add(miValueResult2);
1074 const CMICmnMIValueConst miValueConst3("Interrupt");
1075 const CMICmnMIValueResult miValueResult3("signal-meaning", miValueConst3);
1076 miOutOfBandRecord.Add(miValueResult3);
1077 CMICmnMIValueTuple miValueTuple;
1078 bOk = bOk && MiHelpGetCurrentThreadFrame(miValueTuple);
1079 const CMICmnMIValueResult miValueResult4("frame", miValueTuple);
1080 miOutOfBandRecord.Add(miValueResult4);
1081 const CMIUtilString strThreadId(CMIUtilString::Format(
1082 "%" PRIu32"u", sbProcess.GetSelectedThread().GetIndexID()));
1083 const CMICmnMIValueConst miValueConst5(strThreadId);
1084 const CMICmnMIValueResult miValueResult5("thread-id", miValueConst5);
1085 miOutOfBandRecord.Add(miValueResult5);
1086 const CMICmnMIValueConst miValueConst6("all");
1087 const CMICmnMIValueResult miValueResult6("stopped-threads", miValueConst6);
1088 miOutOfBandRecord.Add(miValueResult6);
1089 bOk = bOk && MiOutOfBandRecordToStdout(miOutOfBandRecord);
1090 bOk = bOk && CMICmnStreamStdout::WritePrompt();
1091 } else if (nStopReason == m_SIGSTOP) {
1092 // MI print
1093 // "*stopped,reason=\"signal-received\",signal-name=\"SIGSTOP\",signal-meaning=\"Stop\",frame={%s},thread-id=\"%d\",stopped-threads=\"all\""
1094 const CMICmnMIValueConst miValueConst("signal-received");
1095 const CMICmnMIValueResult miValueResult("reason", miValueConst);
1096 CMICmnMIOutOfBandRecord miOutOfBandRecord(
1097 CMICmnMIOutOfBandRecord::eOutOfBand_Stopped, miValueResult);
1098 const CMICmnMIValueConst miValueConst2("SIGSTOP");
1099 const CMICmnMIValueResult miValueResult2("signal-name", miValueConst2);
1100 miOutOfBandRecord.Add(miValueResult2);
1101 const CMICmnMIValueConst miValueConst3("Stop");
1102 const CMICmnMIValueResult miValueResult3("signal-meaning", miValueConst3);
1103 miOutOfBandRecord.Add(miValueResult3);
1104 CMICmnMIValueTuple miValueTuple;
1105 bOk = bOk && MiHelpGetCurrentThreadFrame(miValueTuple);
1106 const CMICmnMIValueResult miValueResult4("frame", miValueTuple);
1107 miOutOfBandRecord.Add(miValueResult4);
1108 const CMIUtilString strThreadId(CMIUtilString::Format(
1109 "%" PRIu32"u", sbProcess.GetSelectedThread().GetIndexID()));
1110 const CMICmnMIValueConst miValueConst5(strThreadId);
1111 const CMICmnMIValueResult miValueResult5("thread-id", miValueConst5);
1112 miOutOfBandRecord.Add(miValueResult5);
1113 const CMICmnMIValueConst miValueConst6("all");
1114 const CMICmnMIValueResult miValueResult6("stopped-threads", miValueConst6);
1115 miOutOfBandRecord.Add(miValueResult6);
1116 bOk = bOk && MiOutOfBandRecordToStdout(miOutOfBandRecord);
1117 bOk = bOk && CMICmnStreamStdout::WritePrompt();
1118 } else if (nStopReason == m_SIGSEGV) {
1119 // MI print
1120 // "*stopped,reason=\"signal-received\",signal-name=\"SIGSEGV\",signal-meaning=\"Segmentation
1121 // fault\",thread-id=\"%d\",frame={%s}"
1122 const CMICmnMIValueConst miValueConst("signal-received");
1123 const CMICmnMIValueResult miValueResult("reason", miValueConst);
1124 CMICmnMIOutOfBandRecord miOutOfBandRecord(
1125 CMICmnMIOutOfBandRecord::eOutOfBand_Stopped, miValueResult);
1126 const CMICmnMIValueConst miValueConst2("SIGSEGV");
1127 const CMICmnMIValueResult miValueResult2("signal-name", miValueConst2);
1128 miOutOfBandRecord.Add(miValueResult2);
1129 const CMICmnMIValueConst miValueConst3("Segmentation fault");
1130 const CMICmnMIValueResult miValueResult3("signal-meaning", miValueConst3);
1131 miOutOfBandRecord.Add(miValueResult3);
1132 CMICmnMIValueTuple miValueTuple;
1133 bOk = bOk && MiHelpGetCurrentThreadFrame(miValueTuple);
1134 const CMICmnMIValueResult miValueResult4("frame", miValueTuple);
1135 miOutOfBandRecord.Add(miValueResult4);
1136 const CMIUtilString strThreadId(CMIUtilString::Format(
1137 "%d", sbProcess.GetSelectedThread().GetIndexID()));
1138 const CMICmnMIValueConst miValueConst5(strThreadId);
1139 const CMICmnMIValueResult miValueResult5("thread-id", miValueConst5);
1140 miOutOfBandRecord.Add(miValueResult5);
1141 bOk = bOk && MiOutOfBandRecordToStdout(miOutOfBandRecord);
1142 // Note no "(gdb)" output here
1143 } else if (nStopReason == m_SIGTRAP) {
1144 lldb::SBThread thread = sbProcess.GetSelectedThread();
1145 const MIuint nFrames = thread.GetNumFrames();
1146 if (nFrames > 0) {
1147 lldb::SBFrame frame = thread.GetFrameAtIndex(0);
1148 const char *pFnName = frame.GetFunctionName();
1149 if (pFnName != nullptr) {
1150 const CMIUtilString fnName = CMIUtilString(pFnName);
1151 static const CMIUtilString threadCloneFn =
1152 CMIUtilString("__pthread_clone");
1153
1154 if (CMIUtilString::Compare(threadCloneFn, fnName)) {
1155 if (sbProcess.IsValid())
1156 sbProcess.Continue();
1157 }
1158 }
1159 }
1160 } else {
1161 // MI print
1162 // "*stopped,reason=\"signal-received\",signal-name=\"%s\",thread-id=\"%d\",stopped-threads=\"all\""
1163 // MI print
1164 // "*stopped,reason=\"signal-received\",signal=\"%d\",thread-id=\"%d\",stopped-threads=\"all\""
1165 const CMICmnMIValueConst miValueConst("signal-received");
1166 const CMICmnMIValueResult miValueResult("reason", miValueConst);
1167 CMICmnMIOutOfBandRecord miOutOfBandRecord(
1168 CMICmnMIOutOfBandRecord::eOutOfBand_Stopped, miValueResult);
1169 lldb::SBUnixSignals sbUnixSignals = sbProcess.GetUnixSignals();
1170 const char *pSignal = sbUnixSignals.GetSignalAsCString(nStopReason);
1171 if (pSignal) {
1172 const CMICmnMIValueConst miValueConst2(pSignal);
1173 const CMICmnMIValueResult miValueResult2("signal-name", miValueConst2);
1174 miOutOfBandRecord.Add(miValueResult2);
1175 } else {
1176 const CMIUtilString strSignal(
1177 CMIUtilString::Format("%" PRIu64"l" "u", nStopReason));
1178 const CMICmnMIValueConst miValueConst2(strSignal);
1179 const CMICmnMIValueResult miValueResult2("signal", miValueConst2);
1180 miOutOfBandRecord.Add(miValueResult2);
1181 }
1182 const CMIUtilString strThreadId(CMIUtilString::Format(
1183 "%d", sbProcess.GetSelectedThread().GetIndexID()));
1184 const CMICmnMIValueConst miValueConst3(strThreadId);
1185 const CMICmnMIValueResult miValueResult3("thread-id", miValueConst3);
1186 miOutOfBandRecord.Add(miValueResult3);
1187 const CMICmnMIValueConst miValueConst4("all");
1188 const CMICmnMIValueResult miValueResult4("stopped-threads", miValueConst4);
1189 miOutOfBandRecord.Add(miValueResult4);
1190 bOk = bOk && MiOutOfBandRecordToStdout(miOutOfBandRecord);
1191 bOk = bOk && CMICmnStreamStdout::WritePrompt();
1192 }
1193 return bOk;
1194}
1195
1196//++
1197//------------------------------------------------------------------------------------
1198// Details: Asynchronous event handler for LLDB Process stop exception.
1199// Type: Method.
1200// Args: None.
1201// Return: MIstatus::success - Functional succeeded.
1202// MIstatus::failure - Functional failed.
1203// Throws: None.
1204//--
1205bool CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStopException() {
1206 const lldb::SBProcess sbProcess =
1207 CMICmnLLDBDebugSessionInfo::Instance().GetProcess();
1208 lldb::SBThread sbThread = sbProcess.GetSelectedThread();
1209 const size_t nStopDescriptionLen = sbThread.GetStopDescription(nullptr, 0);
1210 std::unique_ptr<char[]> apStopDescription(new char[nStopDescriptionLen]);
1211 sbThread.GetStopDescription(apStopDescription.get(), nStopDescriptionLen);
1212
1213 // MI print
1214 // "*stopped,reason=\"exception-received\",exception=\"%s\",thread-id=\"%d\",stopped-threads=\"all\""
1215 const CMICmnMIValueConst miValueConst("exception-received");
1216 const CMICmnMIValueResult miValueResult("reason", miValueConst);
1217 CMICmnMIOutOfBandRecord miOutOfBandRecord(
1218 CMICmnMIOutOfBandRecord::eOutOfBand_Stopped, miValueResult);
1219 const CMIUtilString strReason(apStopDescription.get());
1220 const CMICmnMIValueConst miValueConst2(strReason);
1221 const CMICmnMIValueResult miValueResult2("exception", miValueConst2);
1222 miOutOfBandRecord.Add(miValueResult2);
1223 const CMIUtilString strThreadId(
1224 CMIUtilString::Format("%d", sbThread.GetIndexID()));
1225 const CMICmnMIValueConst miValueConst3(strThreadId);
1226 const CMICmnMIValueResult miValueResult3("thread-id", miValueConst3);
1227 miOutOfBandRecord.Add(miValueResult3);
1228 const CMICmnMIValueConst miValueConst4("all");
1229 const CMICmnMIValueResult miValueResult4("stopped-threads", miValueConst4);
1230 miOutOfBandRecord.Add(miValueResult4);
1231 bool bOk = MiOutOfBandRecordToStdout(miOutOfBandRecord);
1232 bOk = bOk && CMICmnStreamStdout::WritePrompt();
1233
1234 return bOk;
1235}
1236
1237//++
1238//------------------------------------------------------------------------------------
1239// Details: Form partial MI response in a MI value tuple object.
1240// Type: Method.
1241// Args: vwrMiValueTuple - (W) MI value tuple object.
1242// Return: MIstatus::success - Functionality succeeded.
1243// MIstatus::failure - Functionality failed.
1244// Throws: None.
1245//--
1246bool CMICmnLLDBDebuggerHandleEvents::MiHelpGetCurrentThreadFrame(
1247 CMICmnMIValueTuple &vwrMiValueTuple) {
1248 CMIUtilString strThreadFrame;
1249 lldb::SBProcess sbProcess =
1250 CMICmnLLDBDebugSessionInfo::Instance().GetProcess();
1251 lldb::SBThread thread = sbProcess.GetSelectedThread();
1252 const MIuint nFrame = thread.GetNumFrames();
1253 if (nFrame == 0) {
1254 // MI print
1255 // "addr=\"??\",func=\"??\",file=\"??\",fullname=\"??\",line=\"??\""
1256 const CMICmnMIValueConst miValueConst("??");
1257 const CMICmnMIValueResult miValueResult("addr", miValueConst);
1258 CMICmnMIValueTuple miValueTuple(miValueResult);
1259 const CMICmnMIValueResult miValueResult2("func", miValueConst);
1260 miValueTuple.Add(miValueResult2);
1261 const CMICmnMIValueResult miValueResult4("file", miValueConst);
1262 miValueTuple.Add(miValueResult4);
1263 const CMICmnMIValueResult miValueResult5("fullname", miValueConst);
1264 miValueTuple.Add(miValueResult5);
1265 const CMICmnMIValueResult miValueResult6("line", miValueConst);
1266 miValueTuple.Add(miValueResult6);
1267
1268 vwrMiValueTuple = miValueTuple;
1269
1270 return MIstatus::success;
1271 }
1272
1273 CMICmnMIValueTuple miValueTuple;
1274 if (!CMICmnLLDBDebugSessionInfo::Instance().MIResponseFormFrameInfo(
1275 thread, 0, CMICmnLLDBDebugSessionInfo::eFrameInfoFormat_NoArguments,
1276 miValueTuple)) {
1277 SetErrorDescription(
1278 CMIUtilString::Format(MIRSRC(IDS_LLDBOUTOFBAND_ERR_FORM_MI_RESPONSE)CMICmnResources::Instance().GetString(IDS_LLDBOUTOFBAND_ERR_FORM_MI_RESPONSE
).c_str()
,
1279 "MiHelpGetCurrentThreadFrame()"));
1280 return MIstatus::failure;
1281 }
1282
1283 vwrMiValueTuple = miValueTuple;
1284
1285 return MIstatus::success;
1286}
1287
1288//++
1289//------------------------------------------------------------------------------------
1290// Details: Asynchronous event handler for LLDB Process stop reason breakpoint.
1291// Type: Method.
1292// Args: None.
1293// Return: MIstatus::success - Functionality succeeded.
1294// MIstatus::failure - Functionality failed.
1295// Throws: None.
1296//--
1297bool CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStopReasonBreakpoint() {
1298 // CODETAG_DEBUG_SESSION_RUNNING_PROG_RECEIVED_SIGINT_PAUSE_PROGRAM
1299 if (!CMIDriver::Instance().SetDriverStateRunningNotDebugging()) {
1300 const CMIUtilString &rErrMsg(CMIDriver::Instance().GetErrorDescription());
1301 SetErrorDescription(CMIUtilString::Format(
1302 MIRSRC(IDS_LLDBOUTOFBAND_ERR_SETNEWDRIVERSTATE)CMICmnResources::Instance().GetString(IDS_LLDBOUTOFBAND_ERR_SETNEWDRIVERSTATE
).c_str()
,
1303 "HandleProcessEventStopReasonBreakpoint()", rErrMsg.c_str()));
1304 return MIstatus::failure;
1305 }
1306
1307 lldb::SBProcess sbProcess =
1308 CMICmnLLDBDebugSessionInfo::Instance().GetProcess();
1309 const MIuint64 brkPtId =
1310 sbProcess.GetSelectedThread().GetStopReasonDataAtIndex(0);
1311 lldb::SBBreakpoint brkPt =
1312 CMICmnLLDBDebugSessionInfo::Instance().GetTarget().GetBreakpointAtIndex(
1313 (MIuint)brkPtId);
1314
1315 return MiStoppedAtBreakPoint(brkPtId, brkPt);
1316}
1317
1318//++
1319//------------------------------------------------------------------------------------
1320// Details: Form the MI Out-of-band response for stopped reason on hitting a
1321// break point.
1322// Type: Method.
1323// Args: vBrkPtId - (R) The LLDB break point's ID
1324// vBrkPt - (R) THe LLDB break point object.
1325// Return: MIstatus::success - Functionality succeeded.
1326// MIstatus::failure - Functionality failed.
1327// Throws: None.
1328//--
1329bool CMICmnLLDBDebuggerHandleEvents::MiStoppedAtBreakPoint(
1330 const MIuint64 vBrkPtId, const lldb::SBBreakpoint &vBrkPt) {
1331 bool bOk = MIstatus::success;
1332
1333 lldb::SBProcess sbProcess =
1334 CMICmnLLDBDebugSessionInfo::Instance().GetProcess();
1335 lldb::SBThread thread = sbProcess.GetSelectedThread();
1336 const MIuint nFrame = thread.GetNumFrames();
1337 if (nFrame == 0) {
1338 // MI print
1339 // "*stopped,reason=\"breakpoint-hit\",disp=\"del\",bkptno=\"%d\",frame={},thread-id=\"%d\",stopped-threads=\"all\""
1340 const CMICmnMIValueConst miValueConst("breakpoint-hit");
1341 const CMICmnMIValueResult miValueResult("reason", miValueConst);
1342 CMICmnMIOutOfBandRecord miOutOfBandRecord(
1343 CMICmnMIOutOfBandRecord::eOutOfBand_Stopped, miValueResult);
1344 const CMICmnMIValueConst miValueConst2("del");
1345 const CMICmnMIValueResult miValueResult2("disp", miValueConst2);
1346 miOutOfBandRecord.Add(miValueResult2);
1347 const CMIUtilString strBkp(CMIUtilString::Format("%d", vBrkPtId));
1348 const CMICmnMIValueConst miValueConst3(strBkp);
1349 CMICmnMIValueResult miValueResult3("bkptno", miValueConst3);
1350 miOutOfBandRecord.Add(miValueResult3);
1351 const CMICmnMIValueConst miValueConst4("{}");
1352 const CMICmnMIValueResult miValueResult4("frame", miValueConst4);
1353 miOutOfBandRecord.Add(miValueResult4);
1354 const CMIUtilString strThreadId(
1355 CMIUtilString::Format("%d", vBrkPt.GetThreadIndex()));
1356 const CMICmnMIValueConst miValueConst5(strThreadId);
1357 const CMICmnMIValueResult miValueResult5("thread-id", miValueConst5);
1358 miOutOfBandRecord.Add(miValueResult5);
1359 const CMICmnMIValueConst miValueConst6("all");
1360 const CMICmnMIValueResult miValueResult6("stopped-threads", miValueConst6);
1361 miOutOfBandRecord.Add(miValueResult6);
1362 bOk = bOk && MiOutOfBandRecordToStdout(miOutOfBandRecord);
1363 bOk = bOk && CMICmnStreamStdout::WritePrompt();
1364 return bOk;
1365 }
1366
1367 CMICmnLLDBDebugSessionInfo &rSessionInfo(
1368 CMICmnLLDBDebugSessionInfo::Instance());
1369
1370 // MI print
1371 // "*stopped,reason=\"breakpoint-hit\",disp=\"del\",bkptno=\"%d\",frame={addr=\"0x%016"
1372 // PRIx64
1373 // "\",func=\"%s\",args=[],file=\"%s\",fullname=\"%s\",line=\"%d\"},thread-id=\"%d\",stopped-threads=\"all\""
1374 const CMICmnMIValueConst miValueConst("breakpoint-hit");
1375 const CMICmnMIValueResult miValueResult("reason", miValueConst);
1376 CMICmnMIOutOfBandRecord miOutOfBandRecord(
1377 CMICmnMIOutOfBandRecord::eOutOfBand_Stopped, miValueResult);
1378 const CMICmnMIValueConst miValueConstA("del");
1379 const CMICmnMIValueResult miValueResultA("disp", miValueConstA);
1380 miOutOfBandRecord.Add(miValueResultA);
1381 const CMIUtilString strBkp(CMIUtilString::Format("%d", vBrkPtId));
1382 const CMICmnMIValueConst miValueConstB(strBkp);
1383 CMICmnMIValueResult miValueResultB("bkptno", miValueConstB);
1384 miOutOfBandRecord.Add(miValueResultB);
1385
1386 // frame={addr=\"0x%016" PRIx64
1387 // "\",func=\"%s\",args=[],file=\"%s\",fullname=\"%s\",line=\"%d\"}
1388 if (bOk) {
1389 CMICmnMIValueTuple miValueTuple;
1390 bOk = bOk &&
1391 rSessionInfo.MIResponseFormFrameInfo(
1392 thread, 0,
1393 CMICmnLLDBDebugSessionInfo::eFrameInfoFormat_AllArguments,
1394 miValueTuple);
1395 const CMICmnMIValueResult miValueResult8("frame", miValueTuple);
1396 miOutOfBandRecord.Add(miValueResult8);
1397 }
1398
1399 // Add to MI thread-id=\"%d\",stopped-threads=\"all\"
1400 if (bOk) {
1401 const CMIUtilString strThreadId(
1402 CMIUtilString::Format("%d", thread.GetIndexID()));
1403 const CMICmnMIValueConst miValueConst8(strThreadId);
1404 const CMICmnMIValueResult miValueResult8("thread-id", miValueConst8);
1405 miOutOfBandRecord.Add(miValueResult8);
1406 }
1407 if (bOk) {
1408 const CMICmnMIValueConst miValueConst9("all");
1409 const CMICmnMIValueResult miValueResult9("stopped-threads", miValueConst9);
1410 miOutOfBandRecord.Add(miValueResult9);
1411 bOk = MiOutOfBandRecordToStdout(miOutOfBandRecord);
1412 bOk = bOk && CMICmnStreamStdout::WritePrompt();
Value stored to 'bOk' is never read
1413 }
1414
1415 return MIstatus::success;
1416}
1417
1418//++
1419//------------------------------------------------------------------------------------
1420// Details: Asynchronous event handler for LLDB Process stop reason trace.
1421// Type: Method.
1422// Args: None.
1423// Return: MIstatus::success - Functionality succeeded.
1424// MIstatus::failure - Functionality failed.
1425// Throws: None.
1426//--
1427bool CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStopReasonTrace() {
1428 bool bOk = true;
1429 lldb::SBProcess sbProcess =
1430 CMICmnLLDBDebugSessionInfo::Instance().GetProcess();
1431 lldb::SBThread thread = sbProcess.GetSelectedThread();
1432 const MIuint nFrame = thread.GetNumFrames();
1433 if (nFrame == 0) {
1434 // MI print "*stopped,reason=\"trace\",stopped-threads=\"all\""
1435 const CMICmnMIValueConst miValueConst("trace");
1436 const CMICmnMIValueResult miValueResult("reason", miValueConst);
1437 CMICmnMIOutOfBandRecord miOutOfBandRecord(
1438 CMICmnMIOutOfBandRecord::eOutOfBand_Stopped, miValueResult);
1439 const CMICmnMIValueConst miValueConst2("all");
1440 const CMICmnMIValueResult miValueResult2("stopped-threads", miValueConst2);
1441 miOutOfBandRecord.Add(miValueResult2);
1442 bOk = MiOutOfBandRecordToStdout(miOutOfBandRecord);
1443 bOk = bOk && CMICmnStreamStdout::WritePrompt();
1444 return bOk;
1445 }
1446
1447 CMICmnLLDBDebugSessionInfo &rSessionInfo(
1448 CMICmnLLDBDebugSessionInfo::Instance());
1449
1450 // MI print
1451 // "*stopped,reason=\"end-stepping-range\",frame={addr=\"0x%016" PRIx64
1452 // "\",func=\"%s\",args=[\"%s\"],file=\"%s\",fullname=\"%s\",line=\"%d\"},thread-id=\"%d\",stopped-threads=\"all\""
1453
1454 // Function args
1455 CMICmnMIValueTuple miValueTuple;
1456 if (!rSessionInfo.MIResponseFormFrameInfo(
1457 thread, 0, CMICmnLLDBDebugSessionInfo::eFrameInfoFormat_AllArguments,
1458 miValueTuple))
1459 return MIstatus::failure;
1460
1461 const CMICmnMIValueConst miValueConst("end-stepping-range");
1462 const CMICmnMIValueResult miValueResult("reason", miValueConst);
1463 CMICmnMIOutOfBandRecord miOutOfBandRecord(
1464 CMICmnMIOutOfBandRecord::eOutOfBand_Stopped, miValueResult);
1465 const CMICmnMIValueResult miValueResult2("frame", miValueTuple);
1466 miOutOfBandRecord.Add(miValueResult2);
1467
1468 // Add to MI thread-id=\"%d\",stopped-threads=\"all\"
1469 const CMIUtilString strThreadId(
1470 CMIUtilString::Format("%d", thread.GetIndexID()));
1471 const CMICmnMIValueConst miValueConst8(strThreadId);
1472 const CMICmnMIValueResult miValueResult8("thread-id", miValueConst8);
1473 miOutOfBandRecord.Add(miValueResult8);
1474
1475 const CMICmnMIValueConst miValueConst9("all");
1476 const CMICmnMIValueResult miValueResult9("stopped-threads", miValueConst9);
1477 miOutOfBandRecord.Add(miValueResult9);
1478 bOk = MiOutOfBandRecordToStdout(miOutOfBandRecord);
1479 bOk = bOk && CMICmnStreamStdout::WritePrompt();
1480
1481 return bOk;
1482}
1483
1484//++
1485//------------------------------------------------------------------------------------
1486// Details: Asynchronous function update selected thread.
1487// Type: Method.
1488// Args: None.
1489// Return: MIstatus::success - Functionality succeeded.
1490// MIstatus::failure - Functionality failed.
1491// Throws: None.
1492//--
1493bool CMICmnLLDBDebuggerHandleEvents::UpdateSelectedThread() {
1494 lldb::SBProcess process = CMICmnLLDBDebugSessionInfo::Instance()
1495 .GetDebugger()
1496 .GetSelectedTarget()
1497 .GetProcess();
1498 if (!process.IsValid())
1499 return MIstatus::success;
1500
1501 lldb::SBThread currentThread = process.GetSelectedThread();
1502 lldb::SBThread thread;
1503 const lldb::StopReason eCurrentThreadStoppedReason =
1504 currentThread.GetStopReason();
1505 if (!currentThread.IsValid() ||
1506 (eCurrentThreadStoppedReason == lldb::eStopReasonInvalid) ||
1507 (eCurrentThreadStoppedReason == lldb::eStopReasonNone)) {
1508 // Prefer a thread that has just completed its plan over another thread as
1509 // current thread
1510 lldb::SBThread planThread;
1511 lldb::SBThread otherThread;
1512 const size_t nThread = process.GetNumThreads();
1513 for (MIuint i = 0; i < nThread; i++) {
1514 // GetThreadAtIndex() uses a base 0 index
1515 // GetThreadByIndexID() uses a base 1 index
1516 thread = process.GetThreadAtIndex(i);
1517 const lldb::StopReason eThreadStopReason = thread.GetStopReason();
1518 switch (eThreadStopReason) {
1519 case lldb::eStopReasonTrace:
1520 case lldb::eStopReasonBreakpoint:
1521 case lldb::eStopReasonWatchpoint:
1522 case lldb::eStopReasonSignal:
1523 case lldb::eStopReasonException:
1524 if (!otherThread.IsValid())
1525 otherThread = thread;
1526 break;
1527 case lldb::eStopReasonPlanComplete:
1528 if (!planThread.IsValid())
1529 planThread = thread;
1530 break;
1531 case lldb::eStopReasonInvalid:
1532 case lldb::eStopReasonNone:
1533 default:
1534 break;
1535 }
1536 }
1537 if (planThread.IsValid())
1538 process.SetSelectedThread(planThread);
1539 else if (otherThread.IsValid())
1540 process.SetSelectedThread(otherThread);
1541 else {
1542 if (currentThread.IsValid())
1543 thread = currentThread;
1544 else
1545 thread = process.GetThreadAtIndex(0);
1546
1547 if (thread.IsValid())
1548 process.SetSelectedThread(thread);
1549 }
1550 } // if( !currentThread.IsValid() || (eCurrentThreadStoppedReason ==
1551 // lldb::eStopReasonInvalid) || (eCurrentThreadStoppedReason ==
1552 // lldb::eStopReasonNone) )
1553
1554 return MIstatus::success;
1555}
1556
1557//++
1558//------------------------------------------------------------------------------------
1559// Details: Print to stdout "*running,thread-id=\"all\"", "(gdb)".
1560// Type: Method.
1561// Args: None.
1562// Return: MIstatus::success - Functionality succeeded.
1563// MIstatus::failure - Functionality failed.
1564// Throws: None.
1565//--
1566bool CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStateRunning() {
1567 CMICmnMIValueConst miValueConst("all");
1568 CMICmnMIValueResult miValueResult("thread-id", miValueConst);
1569 CMICmnMIOutOfBandRecord miOutOfBandRecord(
1570 CMICmnMIOutOfBandRecord::eOutOfBand_Running, miValueResult);
1571 bool bOk = MiOutOfBandRecordToStdout(miOutOfBandRecord);
1572 bOk = bOk && CMICmnStreamStdout::WritePrompt();
1573
1574 return bOk;
1575}
1576
1577//++
1578//------------------------------------------------------------------------------------
1579// Details: Print to stdout "=thread-exited,id=\"%ld\",group-id=\"i1\"",
1580// "=thread-group-exited,id=\"i1\",exit-code=\"0\""),
1581// "*stopped,reason=\"exited-normally\"",
1582// "(gdb)"
1583// Type: Method.
1584// Args: None.
1585// Return: MIstatus::success - Functionality succeeded.
1586// MIstatus::failure - Functionality failed.
1587// Throws: None.
1588//--
1589bool CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStateExited() {
1590 const CMIUtilString strId(CMIUtilString::Format("%ld", 1));
1591 CMICmnMIValueConst miValueConst(strId);
1592 CMICmnMIValueResult miValueResult("id", miValueConst);
1593 CMICmnMIOutOfBandRecord miOutOfBandRecord(
1594 CMICmnMIOutOfBandRecord::eOutOfBand_ThreadExited, miValueResult);
1595 CMICmnMIValueConst miValueConst2("i1");
1596 CMICmnMIValueResult miValueResult2("group-id", miValueConst2);
1597 miOutOfBandRecord.Add(miValueResult2);
1598 bool bOk = MiOutOfBandRecordToStdout(miOutOfBandRecord);
1599 if (bOk) {
1600 CMICmnMIValueConst miValueConst3("i1");
1601 CMICmnMIValueResult miValueResult3("id", miValueConst3);
1602 CMICmnMIOutOfBandRecord miOutOfBandRecord2(
1603 CMICmnMIOutOfBandRecord::eOutOfBand_ThreadGroupExited, miValueResult3);
1604 CMICmnMIValueConst miValueConst2("0");
1605 CMICmnMIValueResult miValueResult2("exit-code", miValueConst2);
1606 miOutOfBandRecord2.Add(miValueResult2);
1607 bOk = bOk && MiOutOfBandRecordToStdout(miOutOfBandRecord2);
1608 }
1609 if (bOk) {
1610 CMICmnMIValueConst miValueConst4("exited-normally");
1611 CMICmnMIValueResult miValueResult4("reason", miValueConst4);
1612 CMICmnMIOutOfBandRecord miOutOfBandRecord3(
1613 CMICmnMIOutOfBandRecord::eOutOfBand_Stopped, miValueResult4);
1614 bOk = MiOutOfBandRecordToStdout(miOutOfBandRecord3);
1615 }
1616 bOk = bOk && CMICmnStreamStdout::WritePrompt();
1617
1618 return bOk;
1619}
1620
1621//++
1622//------------------------------------------------------------------------------------
1623// Details: Drain all stdout so we don't see any output come after we print our
1624// prompts.
1625// The process has stuff waiting for stdout; get it and write it out to
1626// the
1627// appropriate place.
1628// Type: Method.
1629// Args: None.
1630// Return: MIstatus::success - Functionality succeeded.
1631// MIstatus::failure - Functionality failed.
1632// Throws: None.
1633//--
1634bool CMICmnLLDBDebuggerHandleEvents::GetProcessStdout() {
1635 CMIUtilString text;
1636 std::unique_ptr<char[]> apStdoutBuffer(new char[1024]);
1637 lldb::SBProcess process = CMICmnLLDBDebugSessionInfo::Instance()
1638 .GetDebugger()
1639 .GetSelectedTarget()
1640 .GetProcess();
1641 while (1) {
1642 const size_t nBytes = process.GetSTDOUT(apStdoutBuffer.get(), 1024);
1643 text.append(apStdoutBuffer.get(), nBytes);
1644
1645 while (1) {
1646 const size_t nNewLine = text.find('\n');
1647 if (nNewLine == std::string::npos)
1648 break;
1649
1650 const CMIUtilString line(text.substr(0, nNewLine + 1));
1651 text.erase(0, nNewLine + 1);
1652 const bool bEscapeQuotes(true);
1653 CMICmnMIValueConst miValueConst(line.Escape(bEscapeQuotes));
1654 CMICmnMIOutOfBandRecord miOutOfBandRecord(
1655 CMICmnMIOutOfBandRecord::eOutOfBand_TargetStreamOutput, miValueConst);
1656 const bool bOk = MiOutOfBandRecordToStdout(miOutOfBandRecord);
1657 if (!bOk)
1658 return MIstatus::failure;
1659 }
1660
1661 if (nBytes == 0) {
1662 if (!text.empty()) {
1663 const bool bEscapeQuotes(true);
1664 CMICmnMIValueConst miValueConst(text.Escape(bEscapeQuotes));
1665 CMICmnMIOutOfBandRecord miOutOfBandRecord(
1666 CMICmnMIOutOfBandRecord::eOutOfBand_TargetStreamOutput,
1667 miValueConst);
1668 return MiOutOfBandRecordToStdout(miOutOfBandRecord);
1669 }
1670 break;
1671 }
1672 }
1673
1674 return MIstatus::success;
1675}
1676
1677//++
1678//------------------------------------------------------------------------------------
1679// Details: Drain all stderr so we don't see any output come after we print our
1680// prompts.
1681// The process has stuff waiting for stderr; get it and write it out to
1682// the
1683// appropriate place.
1684// Type: Method.
1685// Args: None.
1686// Return: MIstatus::success - Functionality succeeded.
1687// MIstatus::failure - Functionality failed.
1688// Throws: None.
1689//--
1690bool CMICmnLLDBDebuggerHandleEvents::GetProcessStderr() {
1691 CMIUtilString text;
1692 std::unique_ptr<char[]> apStderrBuffer(new char[1024]);
1693 lldb::SBProcess process = CMICmnLLDBDebugSessionInfo::Instance()
1694 .GetDebugger()
1695 .GetSelectedTarget()
1696 .GetProcess();
1697 while (1) {
1698 const size_t nBytes = process.GetSTDERR(apStderrBuffer.get(), 1024);
1699 text.append(apStderrBuffer.get(), nBytes);
1700
1701 while (1) {
1702 const size_t nNewLine = text.find('\n');
1703 if (nNewLine == std::string::npos)
1704 break;
1705
1706 const CMIUtilString line(text.substr(0, nNewLine + 1));
1707 const bool bEscapeQuotes(true);
1708 CMICmnMIValueConst miValueConst(line.Escape(bEscapeQuotes));
1709 CMICmnMIOutOfBandRecord miOutOfBandRecord(
1710 CMICmnMIOutOfBandRecord::eOutOfBand_TargetStreamOutput, miValueConst);
1711 const bool bOk = MiOutOfBandRecordToStdout(miOutOfBandRecord);
1712 if (!bOk)
1713 return MIstatus::failure;
1714 }
1715
1716 if (nBytes == 0) {
1717 if (!text.empty()) {
1718 const bool bEscapeQuotes(true);
1719 CMICmnMIValueConst miValueConst(text.Escape(bEscapeQuotes));
1720 CMICmnMIOutOfBandRecord miOutOfBandRecord(
1721 CMICmnMIOutOfBandRecord::eOutOfBand_TargetStreamOutput,
1722 miValueConst);
1723 return MiOutOfBandRecordToStdout(miOutOfBandRecord);
1724 }
1725 break;
1726 }
1727 }
1728
1729 return MIstatus::success;
1730}
1731
1732//++
1733//------------------------------------------------------------------------------------
1734// Details: Asynchronous event function check for state changes.
1735// Type: Method.
1736// Args: None.
1737// Return: MIstatus::success - Functionality succeeded.
1738// MIstatus::failure - Functionality failed.
1739// Throws: None.
1740//--
1741bool CMICmnLLDBDebuggerHandleEvents::ChkForStateChanges() {
1742 CMICmnLLDBDebugSessionInfo &rSessionInfo(
1743 CMICmnLLDBDebugSessionInfo::Instance());
1744 lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
1745 if (!sbProcess.IsValid())
1746 return MIstatus::success;
1747
1748 // Check for created threads
1749 const MIuint nThread = sbProcess.GetNumThreads();
1750 for (MIuint i = 0; i < nThread; i++) {
1751 // GetThreadAtIndex() uses a base 0 index
1752 // GetThreadByIndexID() uses a base 1 index
1753 lldb::SBThread thread = sbProcess.GetThreadAtIndex(i);
1754 if (!thread.IsValid())
1755 continue;
1756
1757 const MIuint threadIndexID = thread.GetIndexID();
1758 const bool bFound =
1759 std::find(rSessionInfo.m_vecActiveThreadId.cbegin(),
1760 rSessionInfo.m_vecActiveThreadId.cend(),
1761 threadIndexID) != rSessionInfo.m_vecActiveThreadId.end();
1762 if (!bFound) {
1763 rSessionInfo.m_vecActiveThreadId.push_back(threadIndexID);
1764
1765 // Form MI "=thread-created,id=\"%d\",group-id=\"i1\""
1766 const CMIUtilString strValue(CMIUtilString::Format("%d", threadIndexID));
1767 const CMICmnMIValueConst miValueConst(strValue);
1768 const CMICmnMIValueResult miValueResult("id", miValueConst);
1769 CMICmnMIOutOfBandRecord miOutOfBand(
1770 CMICmnMIOutOfBandRecord::eOutOfBand_ThreadCreated, miValueResult);
1771 const CMICmnMIValueConst miValueConst2("i1");
1772 const CMICmnMIValueResult miValueResult2("group-id", miValueConst2);
1773 miOutOfBand.Add(miValueResult2);
1774 bool bOk = MiOutOfBandRecordToStdout(miOutOfBand);
1775 if (!bOk)
1776 return MIstatus::failure;
1777 }
1778 }
1779
1780 lldb::SBThread currentThread = sbProcess.GetSelectedThread();
1781 if (currentThread.IsValid()) {
1782 const MIuint currentThreadIndexID = currentThread.GetIndexID();
1783 if (rSessionInfo.m_currentSelectedThread != currentThreadIndexID) {
1784 rSessionInfo.m_currentSelectedThread = currentThreadIndexID;
1785
1786 // Form MI "=thread-selected,id=\"%d\""
1787 const CMIUtilString strValue(
1788 CMIUtilString::Format("%d", currentThreadIndexID));
1789 const CMICmnMIValueConst miValueConst(strValue);
1790 const CMICmnMIValueResult miValueResult("id", miValueConst);
1791 CMICmnMIOutOfBandRecord miOutOfBand(
1792 CMICmnMIOutOfBandRecord::eOutOfBand_ThreadSelected, miValueResult);
1793 if (!MiOutOfBandRecordToStdout(miOutOfBand))
1794 return MIstatus::failure;
1795 }
1796 }
1797
1798 // Check for invalid (removed) threads
1799 CMICmnLLDBDebugSessionInfo::VecActiveThreadId_t::iterator it =
1800 rSessionInfo.m_vecActiveThreadId.begin();
1801 while (it != rSessionInfo.m_vecActiveThreadId.end()) {
1802 const MIuint threadIndexID = *it;
1803 lldb::SBThread thread = sbProcess.GetThreadByIndexID(threadIndexID);
1804 if (!thread.IsValid()) {
1805 // Form MI "=thread-exited,id=\"%ld\",group-id=\"i1\""
1806 const CMIUtilString strValue(CMIUtilString::Format("%ld", threadIndexID));
1807 const CMICmnMIValueConst miValueConst(strValue);
1808 const CMICmnMIValueResult miValueResult("id", miValueConst);
1809 CMICmnMIOutOfBandRecord miOutOfBand(
1810 CMICmnMIOutOfBandRecord::eOutOfBand_ThreadExited, miValueResult);
1811 const CMICmnMIValueConst miValueConst2("i1");
1812 const CMICmnMIValueResult miValueResult2("group-id", miValueConst2);
1813 miOutOfBand.Add(miValueResult2);
1814 bool bOk = MiOutOfBandRecordToStdout(miOutOfBand);
1815 if (!bOk)
1816 return MIstatus::failure;
1817
1818 // Remove current thread from cache and get next
1819 it = rSessionInfo.m_vecActiveThreadId.erase(it);
1820 } else
1821 // Next
1822 ++it;
1823 }
1824
1825 return CMICmnStreamStdout::WritePrompt();
1826}
1827
1828//++
1829//------------------------------------------------------------------------------------
1830// Details: Take a fully formed MI result record and send to the stdout stream.
1831// Also output to the MI Log file.
1832// Type: Method.
1833// Args: vrMiResultRecord - (R) MI result record object.
1834// Return: MIstatus::success - Functionality succeeded.
1835// MIstatus::failure - Functionality failed.
1836// Throws: None.
1837//--
1838bool CMICmnLLDBDebuggerHandleEvents::MiResultRecordToStdout(
1839 const CMICmnMIResultRecord &vrMiResultRecord) {
1840 return TextToStdout(vrMiResultRecord.GetString());
1841}
1842
1843//++
1844//------------------------------------------------------------------------------------
1845// Details: Take a fully formed MI Out-of-band record and send to the stdout
1846// stream.
1847// Also output to the MI Log file.
1848// Type: Method.
1849// Args: vrMiOutOfBandRecord - (R) MI Out-of-band record object.
1850// Return: MIstatus::success - Functionality succeeded.
1851// MIstatus::failure - Functionality failed.
1852// Throws: None.
1853//--
1854bool CMICmnLLDBDebuggerHandleEvents::MiOutOfBandRecordToStdout(
1855 const CMICmnMIOutOfBandRecord &vrMiOutOfBandRecord) {
1856 return TextToStdout(vrMiOutOfBandRecord.GetString());
1857}
1858
1859//++
1860//------------------------------------------------------------------------------------
1861// Details: Take a text data and send to the stdout stream. Also output to the
1862// MI Log
1863// file.
1864// Type: Method.
1865// Args: vrTxt - (R) Text.
1866// Return: MIstatus::success - Functionality succeeded.
1867// MIstatus::failure - Functionality failed.
1868// Throws: None.
1869//--
1870bool CMICmnLLDBDebuggerHandleEvents::TextToStdout(const CMIUtilString &vrTxt) {
1871 return CMICmnStreamStdout::TextToStdout(vrTxt);
1872}
1873
1874//++
1875//------------------------------------------------------------------------------------
1876// Details: Take a text data and send to the stderr stream. Also output to the
1877// MI Log
1878// file.
1879// Type: Method.
1880// Args: vrTxt - (R) Text.
1881// Return: MIstatus::success - Functionality succeeded.
1882// MIstatus::failure - Functionality failed.
1883// Throws: None.
1884//--
1885bool CMICmnLLDBDebuggerHandleEvents::TextToStderr(const CMIUtilString &vrTxt) {
1886 return CMICmnStreamStderr::TextToStderr(vrTxt);
1887}
1888
1889//++
1890//------------------------------------------------------------------------------------
1891// Details: Initialize the member variables with the signal values in this
1892// process
1893// file.
1894// Type: Method.
1895// Args: None
1896// Return: Noen
1897// Throws: None.
1898//--
1899void CMICmnLLDBDebuggerHandleEvents::InitializeSignals() {
1900 if (!m_bSignalsInitialized) {
1901 lldb::SBProcess sbProcess =
1902 CMICmnLLDBDebugSessionInfo::Instance().GetProcess();
1903 if (sbProcess.IsValid()) {
1904 lldb::SBUnixSignals unix_signals = sbProcess.GetUnixSignals();
1905 m_SIGINT = unix_signals.GetSignalNumberFromName("SIGINT");
1906 m_SIGSTOP = unix_signals.GetSignalNumberFromName("SIGSTOP");
1907 m_SIGSEGV = unix_signals.GetSignalNumberFromName("SIGSEGV");
1908 m_SIGTRAP = unix_signals.GetSignalNumberFromName("SIGTRAP");
1909 m_bSignalsInitialized = true;
1910 }
1911 }
1912}