Bug Summary

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

Annotated Source Code

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