Bug Summary

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