Bug Summary

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