Bug Summary

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