1 //===-- MICmnLLDBDebuggerHandleEvents.cpp --------------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
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"
22 #include <io.h> // For the ::_access()
24 #include <unistd.h> // For the ::access()
28 #include "MICmnLLDBDebuggerHandleEvents.h"
29 #include "MICmnResources.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"
41 #include "Platform.h" // for PATH_MAX
43 //++ ------------------------------------------------------------------------------------
44 // Details: CMICmnLLDBDebuggerHandleEvents constructor.
50 CMICmnLLDBDebuggerHandleEvents::CMICmnLLDBDebuggerHandleEvents(void)
54 //++ ------------------------------------------------------------------------------------
55 // Details: CMICmnLLDBDebuggerHandleEvents destructor.
61 CMICmnLLDBDebuggerHandleEvents::~CMICmnLLDBDebuggerHandleEvents(void)
66 //++ ------------------------------------------------------------------------------------
67 // Details: Initialize resources for *this broadcaster object.
70 // Return: MIstatus::success - Functionality succeeded.
71 // MIstatus::failure - Functionality failed.
75 CMICmnLLDBDebuggerHandleEvents::Initialize(void)
77 m_clientUsageRefCnt++;
80 return MIstatus::success;
82 m_bInitialized = MIstatus::success;
83 m_bSignalsInitialized = false;
89 return m_bInitialized;
92 //++ ------------------------------------------------------------------------------------
93 // Details: Release resources for *this broadcaster object.
96 // Return: MIstatus::success - Functionality succeeded.
97 // MIstatus::failure - Functionality failed.
101 CMICmnLLDBDebuggerHandleEvents::Shutdown(void)
103 if (--m_clientUsageRefCnt > 0)
104 return MIstatus::success;
107 return MIstatus::success;
109 m_bInitialized = false;
111 return MIstatus::success;
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.
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.
125 CMICmnLLDBDebuggerHandleEvents::HandleEvent(const lldb::SBEvent &vEvent, bool &vrbHandledEvent)
127 bool bOk = MIstatus::success;
128 vrbHandledEvent = false;
130 if (lldb::SBProcess::EventIsProcessEvent(vEvent))
132 vrbHandledEvent = true;
133 bOk = HandleEventSBProcess(vEvent);
135 else if (lldb::SBBreakpoint::EventIsBreakpointEvent(vEvent))
137 vrbHandledEvent = true;
138 bOk = HandleEventSBBreakPoint(vEvent);
140 else if (lldb::SBThread::EventIsThreadEvent(vEvent))
142 vrbHandledEvent = true;
143 bOk = HandleEventSBThread(vEvent);
145 else if (lldb::SBTarget::EventIsTargetEvent(vEvent))
147 vrbHandledEvent = true;
148 bOk = HandleEventSBTarget(vEvent);
150 else if (lldb::SBCommandInterpreter::EventIsCommandInterpreterEvent(vEvent))
152 vrbHandledEvent = true;
153 bOk = HandleEventSBCommandInterpreter(vEvent);
159 //++ ------------------------------------------------------------------------------------
160 // Details: Handle a LLDB SBProcess event.
162 // Args: vEvent - (R) An LLDB broadcast event.
163 // Return: MIstatus::success - Functionality succeeded.
164 // MIstatus::failure - Functionality failed.
168 CMICmnLLDBDebuggerHandleEvents::HandleEventSBProcess(const lldb::SBEvent &vEvent)
170 bool bOk = MIstatus::success;
172 const char *pEventType = "";
173 const MIuint nEventType = vEvent.GetType();
176 case lldb::SBProcess::eBroadcastBitInterrupt:
177 pEventType = "eBroadcastBitInterrupt";
179 case lldb::SBProcess::eBroadcastBitProfileData:
180 pEventType = "eBroadcastBitProfileData";
182 case lldb::SBProcess::eBroadcastBitStateChanged:
183 pEventType = "eBroadcastBitStateChanged";
184 bOk = HandleProcessEventBroadcastBitStateChanged(vEvent);
186 case lldb::SBProcess::eBroadcastBitSTDERR:
187 pEventType = "eBroadcastBitSTDERR";
188 bOk = GetProcessStderr();
190 case lldb::SBProcess::eBroadcastBitSTDOUT:
191 pEventType = "eBroadcastBitSTDOUT";
192 bOk = GetProcessStdout();
196 const CMIUtilString msg(CMIUtilString::Format(MIRSRC(IDS_LLDBOUTOFBAND_ERR_UNKNOWN_EVENT), "SBProcess", (MIuint)nEventType));
197 SetErrorDescription(msg);
198 return MIstatus::failure;
201 m_pLog->WriteLog(CMIUtilString::Format("##### An SB Process event occurred: %s", pEventType));
206 //++ ------------------------------------------------------------------------------------
207 // Details: Handle a LLDB SBBreakpoint event.
209 // Args: vEvent - (R) An LLDB broadcast event.
210 // Return: MIstatus::success - Functionality succeeded.
211 // MIstatus::failure - Functionality failed.
215 CMICmnLLDBDebuggerHandleEvents::HandleEventSBBreakPoint(const lldb::SBEvent &vEvent)
217 bool bOk = MIstatus::success;
219 const char *pEventType = "";
220 const lldb::BreakpointEventType eEvent = lldb::SBBreakpoint::GetBreakpointEventTypeFromEvent(vEvent);
223 case lldb::eBreakpointEventTypeThreadChanged:
224 pEventType = "eBreakpointEventTypeThreadChanged";
226 case lldb::eBreakpointEventTypeLocationsRemoved:
227 pEventType = "eBreakpointEventTypeLocationsRemoved";
229 case lldb::eBreakpointEventTypeInvalidType:
230 pEventType = "eBreakpointEventTypeInvalidType";
232 case lldb::eBreakpointEventTypeLocationsAdded:
233 pEventType = "eBreakpointEventTypeLocationsAdded";
234 bOk = HandleEventSBBreakpointLocationsAdded(vEvent);
236 case lldb::eBreakpointEventTypeAdded:
237 pEventType = "eBreakpointEventTypeAdded";
238 bOk = HandleEventSBBreakpointAdded(vEvent);
240 case lldb::eBreakpointEventTypeRemoved:
241 pEventType = "eBreakpointEventTypeRemoved";
242 bOk = HandleEventSBBreakpointCmn(vEvent);
244 case lldb::eBreakpointEventTypeLocationsResolved:
245 pEventType = "eBreakpointEventTypeLocationsResolved";
246 bOk = HandleEventSBBreakpointCmn(vEvent);
248 case lldb::eBreakpointEventTypeEnabled:
249 pEventType = "eBreakpointEventTypeEnabled";
250 bOk = HandleEventSBBreakpointCmn(vEvent);
252 case lldb::eBreakpointEventTypeDisabled:
253 pEventType = "eBreakpointEventTypeDisabled";
254 bOk = HandleEventSBBreakpointCmn(vEvent);
256 case lldb::eBreakpointEventTypeCommandChanged:
257 pEventType = "eBreakpointEventTypeCommandChanged";
258 bOk = HandleEventSBBreakpointCmn(vEvent);
260 case lldb::eBreakpointEventTypeConditionChanged:
261 pEventType = "eBreakpointEventTypeConditionChanged";
262 bOk = HandleEventSBBreakpointCmn(vEvent);
264 case lldb::eBreakpointEventTypeIgnoreChanged:
265 pEventType = "eBreakpointEventTypeIgnoreChanged";
266 bOk = HandleEventSBBreakpointCmn(vEvent);
269 m_pLog->WriteLog(CMIUtilString::Format("##### An SB Breakpoint event occurred: %s", pEventType));
274 //++ ------------------------------------------------------------------------------------
275 // Details: Handle a LLDB SBBreakpoint event.
277 // Args: vEvent - (R) An LLDB broadcast event.
278 // Return: MIstatus::success - Functionality succeeded.
279 // MIstatus::failure - Functionality failed.
283 CMICmnLLDBDebuggerHandleEvents::HandleEventSBBreakpointLocationsAdded(const lldb::SBEvent &vEvent)
285 const MIuint nLoc = lldb::SBBreakpoint::GetNumBreakpointLocationsFromEvent(vEvent);
287 return MIstatus::success;
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()));
293 return TextToStdout(msg);
296 //++ ------------------------------------------------------------------------------------
297 // Details: Handle a LLDB SBBreakpoint event.
299 // Args: vEvent - (R) An LLDB broadcast event.
300 // Return: MIstatus::success - Functionality succeeded.
301 // MIstatus::failure - Functionality failed.
305 CMICmnLLDBDebuggerHandleEvents::HandleEventSBBreakpointCmn(const lldb::SBEvent &vEvent)
307 lldb::SBBreakpoint brkPt = lldb::SBBreakpoint::GetBreakpointFromEvent(vEvent);
308 if (!brkPt.IsValid())
309 return MIstatus::success;
311 CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
312 CMICmnLLDBDebugSessionInfo::SBrkPtInfo sBrkPtInfo;
313 if (!rSessionInfo.GetBrkPtInfo(brkPt, sBrkPtInfo))
316 CMIUtilString::Format(MIRSRC(IDS_LLDBOUTOFBAND_ERR_BRKPT_INFO_GET), "HandleEventSBBreakpointCmn()", brkPt.GetID()));
317 return MIstatus::failure;
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))
327 CMIUtilString::Format(MIRSRC(IDS_LLDBOUTOFBAND_ERR_BRKPT_NOTFOUND), "HandleEventSBBreakpointCmn()", brkPt.GetID()));
328 return MIstatus::failure;
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;
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))
348 SetErrorDescription(CMIUtilString::Format(MIRSRC(IDS_LLDBOUTOFBAND_ERR_FORM_MI_RESPONSE), "HandleEventSBBreakpointCmn()"));
349 return MIstatus::failure;
352 const CMICmnMIValueResult miValueResultC("bkpt", miValueTuple);
353 const CMICmnMIOutOfBandRecord miOutOfBandRecord(CMICmnMIOutOfBandRecord::eOutOfBand_BreakPointModified, miValueResultC);
354 const bool bOk = MiOutOfBandRecordToStdout(miOutOfBandRecord);
359 //++ ------------------------------------------------------------------------------------
360 // Details: Handle a LLDB SBBreakpoint added event.
361 // Add more breakpoint information or overwrite existing information.
362 // Normally a break point session info objects exists by now when an MI command
363 // was issued to insert a break so the retrieval would normally always succeed
364 // however should a user type "b main" into a console then LLDB will create a
365 // breakpoint directly, hence no MI command, hence no previous record of the
366 // breakpoint so RecordBrkPtInfoGet() will fail. We still get the event though
367 // so need to create a breakpoint info object here and send appropriate MI
370 // Args: vEvent - (R) An LLDB broadcast event.
371 // Return: MIstatus::success - Functionality succeeded.
372 // MIstatus::failure - Functionality failed.
376 CMICmnLLDBDebuggerHandleEvents::HandleEventSBBreakpointAdded(const lldb::SBEvent &vEvent)
378 lldb::SBBreakpoint brkPt = lldb::SBBreakpoint::GetBreakpointFromEvent(vEvent);
379 if (!brkPt.IsValid())
380 return MIstatus::success;
382 CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
383 CMICmnLLDBDebugSessionInfo::SBrkPtInfo sBrkPtInfo;
384 if (!rSessionInfo.GetBrkPtInfo(brkPt, sBrkPtInfo))
387 CMIUtilString::Format(MIRSRC(IDS_LLDBOUTOFBAND_ERR_BRKPT_INFO_GET), "HandleEventSBBreakpointAdded()", brkPt.GetID()));
388 return MIstatus::failure;
391 // CODETAG_LLDB_BREAKPOINT_CREATION
392 // This is in a worker thread
393 CMICmnLLDBDebugSessionInfo::SBrkPtInfo sBrkPtInfoRec;
394 const bool bBrkPtExistAlready = rSessionInfo.RecordBrkPtInfoGet(brkPt.GetID(), sBrkPtInfoRec);
395 if (bBrkPtExistAlready)
397 // Update breakpoint information object
398 sBrkPtInfo.m_bDisp = sBrkPtInfoRec.m_bDisp;
399 sBrkPtInfo.m_bEnabled = brkPt.IsEnabled();
400 sBrkPtInfo.m_bHaveArgOptionThreadGrp = false;
401 sBrkPtInfo.m_strOptThrdGrp.clear();
402 sBrkPtInfo.m_nTimes = brkPt.GetHitCount();
403 sBrkPtInfo.m_strOrigLoc = sBrkPtInfoRec.m_strOrigLoc;
404 sBrkPtInfo.m_nIgnore = sBrkPtInfoRec.m_nIgnore;
405 sBrkPtInfo.m_bPending = sBrkPtInfoRec.m_bPending;
406 sBrkPtInfo.m_bCondition = sBrkPtInfoRec.m_bCondition;
407 sBrkPtInfo.m_strCondition = sBrkPtInfoRec.m_strCondition;
408 sBrkPtInfo.m_bBrkPtThreadId = sBrkPtInfoRec.m_bBrkPtThreadId;
409 sBrkPtInfo.m_nBrkPtThreadId = sBrkPtInfoRec.m_nBrkPtThreadId;
413 // Create a breakpoint information object
414 sBrkPtInfo.m_bDisp = brkPt.IsOneShot();
415 sBrkPtInfo.m_bEnabled = brkPt.IsEnabled();
416 sBrkPtInfo.m_bHaveArgOptionThreadGrp = false;
417 sBrkPtInfo.m_strOptThrdGrp.clear();
418 sBrkPtInfo.m_strOrigLoc = CMIUtilString::Format("%s:%d", sBrkPtInfo.m_fileName.c_str(), sBrkPtInfo.m_nLine);
419 sBrkPtInfo.m_nIgnore = brkPt.GetIgnoreCount();
420 sBrkPtInfo.m_bPending = false;
421 const char *pStrCondition = brkPt.GetCondition();
422 sBrkPtInfo.m_bCondition = (pStrCondition != nullptr) ? true : false;
423 sBrkPtInfo.m_strCondition = (pStrCondition != nullptr) ? pStrCondition : "??";
424 sBrkPtInfo.m_bBrkPtThreadId = (brkPt.GetThreadID() != 0) ? true : false;
425 sBrkPtInfo.m_nBrkPtThreadId = brkPt.GetThreadID();
428 CMICmnMIValueTuple miValueTuple;
429 if (!rSessionInfo.MIResponseFormBrkPtInfo(sBrkPtInfo, miValueTuple))
431 SetErrorDescription(CMIUtilString::Format(MIRSRC(IDS_LLDBOUTOFBAND_ERR_FORM_MI_RESPONSE), "HandleEventSBBreakpointAdded()"));
432 return MIstatus::failure;
435 bool bOk = MIstatus::success;
436 if (bBrkPtExistAlready)
439 // "=breakpoint-modified,bkpt={number=\"%d\",type=\"breakpoint\",disp=\"%s\",enabled=\"%c\",addr=\"0x%016" PRIx64 "\",func=\"%s\",file=\"%s\",fullname=\"%s/%s\",line=\"%d\",times=\"%d\",original-location=\"%s\"}"
440 const CMICmnMIValueResult miValueResult("bkpt", miValueTuple);
441 const CMICmnMIOutOfBandRecord miOutOfBandRecord(CMICmnMIOutOfBandRecord::eOutOfBand_BreakPointModified, miValueResult);
442 bOk = MiOutOfBandRecordToStdout(miOutOfBandRecord);
446 // CODETAG_LLDB_BRKPT_ID_MAX
447 if (brkPt.GetID() > (lldb::break_id_t)rSessionInfo.m_nBrkPointCntMax)
449 SetErrorDescription(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_BRKPT_CNT_EXCEEDED), "HandleEventSBBreakpointAdded()",
450 rSessionInfo.m_nBrkPointCntMax, sBrkPtInfo.m_id));
451 return MIstatus::failure;
453 if (!rSessionInfo.RecordBrkPtInfo(brkPt.GetID(), sBrkPtInfo))
456 CMIUtilString::Format(MIRSRC(IDS_LLDBOUTOFBAND_ERR_BRKPT_INFO_SET), "HandleEventSBBreakpointAdded()", sBrkPtInfo.m_id));
457 return MIstatus::failure;
461 // "=breakpoint-created,bkpt={number=\"%d\",type=\"breakpoint\",disp=\"%s\",enabled=\"%c\",addr=\"0x%016" PRIx64 "\",func=\"%s\",file=\"%s\",fullname=\"%s/%s\",line=\"%d\",times=\"%d\",original-location=\"%s\"}"
462 const CMICmnMIValueResult miValueResult("bkpt", miValueTuple);
463 const CMICmnMIOutOfBandRecord miOutOfBandRecord(CMICmnMIOutOfBandRecord::eOutOfBand_BreakPointCreated, miValueResult);
464 bOk = MiOutOfBandRecordToStdout(miOutOfBandRecord);
470 //++ ------------------------------------------------------------------------------------
471 // Details: Handle a LLDB SBThread event.
473 // Args: vEvent - (R) An LLDB broadcast event.
474 // Return: MIstatus::success - Functionality succeeded.
475 // MIstatus::failure - Functionality failed.
479 CMICmnLLDBDebuggerHandleEvents::HandleEventSBThread(const lldb::SBEvent &vEvent)
481 if (!ChkForStateChanges())
482 return MIstatus::failure;
484 bool bOk = MIstatus::success;
485 const char *pEventType = "";
486 const MIuint nEventType = vEvent.GetType();
489 case lldb::SBThread::eBroadcastBitStackChanged:
490 pEventType = "eBroadcastBitStackChanged";
491 bOk = HandleEventSBThreadBitStackChanged(vEvent);
493 case lldb::SBThread::eBroadcastBitThreadSuspended:
494 pEventType = "eBroadcastBitThreadSuspended";
495 bOk = HandleEventSBThreadSuspended(vEvent);
497 case lldb::SBThread::eBroadcastBitThreadResumed:
498 pEventType = "eBroadcastBitThreadResumed";
500 case lldb::SBThread::eBroadcastBitSelectedFrameChanged:
501 pEventType = "eBroadcastBitSelectedFrameChanged";
503 case lldb::SBThread::eBroadcastBitThreadSelected:
504 pEventType = "eBroadcastBitThreadSelected";
508 const CMIUtilString msg(CMIUtilString::Format(MIRSRC(IDS_LLDBOUTOFBAND_ERR_UNKNOWN_EVENT), "SBThread", (MIuint)nEventType));
509 SetErrorDescription(msg);
510 return MIstatus::failure;
513 m_pLog->WriteLog(CMIUtilString::Format("##### An SBThread event occurred: %s", pEventType));
518 //++ ------------------------------------------------------------------------------------
519 // Details: Handle a LLDB SBThread event.
521 // Args: vEvent - (R) An LLDB broadcast event.
522 // Return: MIstatus::success - Functionality succeeded.
523 // MIstatus::failure - Functionality failed.
527 CMICmnLLDBDebuggerHandleEvents::HandleEventSBThreadSuspended(const lldb::SBEvent &vEvent)
529 lldb::SBThread thread = lldb::SBThread::GetThreadFromEvent(vEvent);
530 if (!thread.IsValid())
531 return MIstatus::success;
533 const lldb::StopReason eStopReason = thread.GetStopReason();
534 if (eStopReason != lldb::eStopReasonSignal)
535 return MIstatus::success;
537 // MI print "@thread=%d,signal=%lld"
538 const MIuint64 nId = thread.GetStopReasonDataAtIndex(0);
539 const CMIUtilString strThread(CMIUtilString::Format("%d", thread.GetThreadID()));
540 const CMICmnMIValueConst miValueConst(strThread);
541 const CMICmnMIValueResult miValueResult("thread", miValueConst);
542 CMICmnMIOutOfBandRecord miOutOfBandRecord(CMICmnMIOutOfBandRecord::eOutOfBand_Thread, miValueResult);
543 const CMIUtilString strSignal(CMIUtilString::Format("%lld", nId));
544 const CMICmnMIValueConst miValueConst2(strSignal);
545 const CMICmnMIValueResult miValueResult2("signal", miValueConst2);
546 bool bOk = miOutOfBandRecord.Add(miValueResult2);
547 bOk = bOk && MiOutOfBandRecordToStdout(miOutOfBandRecord);
552 //++ ------------------------------------------------------------------------------------
553 // Details: Handle a LLDB SBThread event.
555 // Args: vEvent - (R) An LLDB broadcast event.
556 // Return: MIstatus::success - Functionality succeeded.
557 // MIstatus::failure - Functionality failed.
561 CMICmnLLDBDebuggerHandleEvents::HandleEventSBThreadBitStackChanged(const lldb::SBEvent &vEvent)
563 lldb::SBThread thread = lldb::SBThread::GetThreadFromEvent(vEvent);
564 if (!thread.IsValid())
565 return MIstatus::success;
567 lldb::SBStream streamOut;
568 const bool bOk = thread.GetStatus(streamOut);
569 return bOk && TextToStdout(streamOut.GetData());
572 //++ ------------------------------------------------------------------------------------
573 // Details: Handle a LLDB SBTarget event.
575 // Args: vEvent - (R) An LLDB broadcast event.
576 // Return: MIstatus::success - Functional succeeded.
577 // MIstatus::failure - Functional failed.
581 CMICmnLLDBDebuggerHandleEvents::HandleEventSBTarget(const lldb::SBEvent &vEvent)
583 if (!ChkForStateChanges())
584 return MIstatus::failure;
586 bool bOk = MIstatus::success;
587 const char *pEventType = "";
588 const MIuint nEventType = vEvent.GetType();
591 case lldb::SBTarget::eBroadcastBitBreakpointChanged:
592 pEventType = "eBroadcastBitBreakpointChanged";
594 case lldb::SBTarget::eBroadcastBitModulesLoaded:
595 pEventType = "eBroadcastBitModulesLoaded";
596 bOk = HandleTargetEventBroadcastBitModulesLoaded(vEvent);
598 case lldb::SBTarget::eBroadcastBitModulesUnloaded:
599 pEventType = "eBroadcastBitModulesUnloaded";
600 bOk = HandleTargetEventBroadcastBitModulesUnloaded(vEvent);
602 case lldb::SBTarget::eBroadcastBitWatchpointChanged:
603 pEventType = "eBroadcastBitWatchpointChanged";
605 case lldb::SBTarget::eBroadcastBitSymbolsLoaded:
606 pEventType = "eBroadcastBitSymbolsLoaded";
610 const CMIUtilString msg(CMIUtilString::Format(MIRSRC(IDS_LLDBOUTOFBAND_ERR_UNKNOWN_EVENT), "SBTarget", (MIuint)nEventType));
611 SetErrorDescription(msg);
612 return MIstatus::failure;
615 m_pLog->WriteLog(CMIUtilString::Format("##### An SBTarget event occurred: %s", pEventType));
620 //++ ------------------------------------------------------------------------------------
621 // Details: Print to stdout "=library-loaded,id=\"%s\",target-name=\"%s\",host-name=\"%s\",symbols-loaded="%d"[,symbols-path=\"%s\"],loaded_addr=\"0x%016" PRIx64"\""
624 // Return: MIstatus::success - Function succeeded.
625 // MIstatus::failure - Function failed.
629 CMICmnLLDBDebuggerHandleEvents::HandleTargetEventBroadcastBitModulesLoaded(const lldb::SBEvent &vEvent)
631 bool bOk = MIstatus::failure;
632 const MIuint nSize = lldb::SBTarget::GetNumModulesFromEvent(vEvent);
633 for (MIuint nIndex = 0; nIndex < nSize; ++nIndex)
635 const lldb::SBModule sbModule = lldb::SBTarget::GetModuleAtIndexFromEvent(nIndex, vEvent);
636 CMICmnMIOutOfBandRecord miOutOfBandRecord(CMICmnMIOutOfBandRecord::eOutOfBand_TargetModuleLoaded);
637 const bool bWithExtraFields = true;
638 bOk = MiHelpGetModuleInfo(sbModule, bWithExtraFields, miOutOfBandRecord);
639 bOk = bOk && MiOutOfBandRecordToStdout(miOutOfBandRecord);
647 //++ ------------------------------------------------------------------------------------
648 // Details: Print to stdout "=library-unloaded,id=\"%s\",target-name=\"%s\",host-name=\"%s\",symbols-loaded="%d"[,symbols-path=\"%s\"],loaded_addr=\"0x%016" PRIx64"\""
651 // Return: MIstatus::success - Function succeeded.
652 // MIstatus::failure - Function failed.
656 CMICmnLLDBDebuggerHandleEvents::HandleTargetEventBroadcastBitModulesUnloaded(const lldb::SBEvent &vEvent)
658 bool bOk = MIstatus::failure;
659 const MIuint nSize = lldb::SBTarget::GetNumModulesFromEvent(vEvent);
660 for (MIuint nIndex = 0; nIndex < nSize; ++nIndex)
662 const lldb::SBModule sbModule = lldb::SBTarget::GetModuleAtIndexFromEvent(nIndex, vEvent);
663 CMICmnMIOutOfBandRecord miOutOfBandRecord(CMICmnMIOutOfBandRecord::eOutOfBand_TargetModuleUnloaded);
664 const bool bWithExtraFields = false;
665 bOk = MiHelpGetModuleInfo(sbModule, bWithExtraFields, miOutOfBandRecord);
666 bOk = bOk && MiOutOfBandRecordToStdout(miOutOfBandRecord);
674 //++ ------------------------------------------------------------------------------------
675 // Details: Build module information for =library-loaded/=library-unloaded: "id=\"%s\",target-name=\"%s\",host-name=\"%s\",symbols-loaded="%d"[,symbols-path=\"%s\"],loaded_addr=\"0x%016" PRIx64"\""
677 // Args: vwrMiValueList - (W) MI value list object.
678 // Return: MIstatus::success - Function succeeded.
679 // MIstatus::failure - Function failed.
683 CMICmnLLDBDebuggerHandleEvents::MiHelpGetModuleInfo(const lldb::SBModule &vModule, const bool vbWithExtraFields,
684 CMICmnMIOutOfBandRecord &vwrMiOutOfBandRecord)
686 bool bOk = MIstatus::success;
688 // First, build standard fields:
690 std::unique_ptr<char[]> apPath(new char[PATH_MAX]);
691 vModule.GetFileSpec().GetPath(apPath.get(), PATH_MAX);
692 const CMIUtilString strTargetPath(apPath.get());
693 const CMICmnMIValueConst miValueConst(strTargetPath);
694 const CMICmnMIValueResult miValueResult("id", miValueConst);
695 bOk = bOk && vwrMiOutOfBandRecord.Add(miValueResult);
696 // Build "target-name" field
697 const CMICmnMIValueConst miValueConst2(strTargetPath);
698 const CMICmnMIValueResult miValueResult2("target-name", miValueConst2);
699 bOk = bOk && vwrMiOutOfBandRecord.Add(miValueResult2);
700 // Build "host-name" field
701 vModule.GetPlatformFileSpec().GetPath(apPath.get(), PATH_MAX);
702 const CMIUtilString strHostPath(apPath.get());
703 const CMICmnMIValueConst miValueConst3(strHostPath);
704 const CMICmnMIValueResult miValueResult3("host-name", miValueConst3);
705 bOk = bOk && vwrMiOutOfBandRecord.Add(miValueResult3);
707 // Then build extra fields if needed:
708 if (vbWithExtraFields)
710 // Build "symbols-loaded" field
711 vModule.GetSymbolFileSpec().GetPath(apPath.get(), PATH_MAX);
712 const CMIUtilString strSymbolsPath(apPath.get());
713 const bool bSymbolsLoaded = !CMIUtilString::Compare(strHostPath, strSymbolsPath);
714 const CMICmnMIValueConst miValueConst4(CMIUtilString::Format("%d", bSymbolsLoaded));
715 const CMICmnMIValueResult miValueResult4("symbols-loaded", miValueConst4);
716 bOk = bOk && vwrMiOutOfBandRecord.Add(miValueResult4);
717 // Build "symbols-path" field
720 const CMICmnMIValueConst miValueConst5(strSymbolsPath);
721 const CMICmnMIValueResult miValueResult5("symbols-path", miValueConst5);
722 bOk = bOk && vwrMiOutOfBandRecord.Add(miValueResult5);
724 // Build "loaded_addr" field
725 const lldb::SBAddress sbAddress(vModule.GetObjectFileHeaderAddress());
726 CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
727 const lldb::addr_t nLoadAddress(sbAddress.GetLoadAddress(rSessionInfo.GetTarget()));
728 const CMIUtilString strLoadedAddr(nLoadAddress != LLDB_INVALID_ADDRESS ?
729 CMIUtilString::Format("0x%016" PRIx64, nLoadAddress) : "-");
730 const CMICmnMIValueConst miValueConst6(strLoadedAddr);
731 const CMICmnMIValueResult miValueResult6("loaded_addr", miValueConst6);
732 bOk = bOk && vwrMiOutOfBandRecord.Add(miValueResult6);
738 //++ ------------------------------------------------------------------------------------
739 // Details: Handle a LLDB SBCommandInterpreter event.
741 // Args: vEvent - (R) An LLDB command interpreter event.
742 // Return: MIstatus::success - Functionality succeeded.
743 // MIstatus::failure - Functionality failed.
747 CMICmnLLDBDebuggerHandleEvents::HandleEventSBCommandInterpreter(const lldb::SBEvent &vEvent)
749 // This function is not used
750 // *** This function is under development
752 const char *pEventType = "";
753 const MIuint nEventType = vEvent.GetType();
756 case lldb::SBCommandInterpreter::eBroadcastBitThreadShouldExit:
757 pEventType = "eBroadcastBitThreadShouldExit";
758 // ToDo: IOR: Reminder to maybe handle this here
759 // const MIuint nEventType = event.GetType();
760 // if (nEventType & lldb::SBCommandInterpreter::eBroadcastBitThreadShouldExit)
762 // m_pClientDriver->SetExitApplicationFlag();
763 // vrbYesExit = true;
764 // return MIstatus::success;
766 case lldb::SBCommandInterpreter::eBroadcastBitResetPrompt:
767 pEventType = "eBroadcastBitResetPrompt";
769 case lldb::SBCommandInterpreter::eBroadcastBitQuitCommandReceived:
771 pEventType = "eBroadcastBitQuitCommandReceived";
772 const bool bForceExit = true;
773 CMICmnLLDBDebugger::Instance().GetDriver().SetExitApplicationFlag(bForceExit);
776 case lldb::SBCommandInterpreter::eBroadcastBitAsynchronousOutputData:
777 pEventType = "eBroadcastBitAsynchronousOutputData";
779 case lldb::SBCommandInterpreter::eBroadcastBitAsynchronousErrorData:
780 pEventType = "eBroadcastBitAsynchronousErrorData";
784 const CMIUtilString msg(
785 CMIUtilString::Format(MIRSRC(IDS_LLDBOUTOFBAND_ERR_UNKNOWN_EVENT), "SBCommandInterpreter", (MIuint)nEventType));
786 SetErrorDescription(msg);
787 return MIstatus::failure;
790 m_pLog->WriteLog(CMIUtilString::Format("##### An SBCommandInterpreter event occurred: %s", pEventType));
792 return MIstatus::success;
795 //++ ------------------------------------------------------------------------------------
796 // Details: Handle SBProcess event eBroadcastBitStateChanged.
798 // Args: vEvent - (R) An LLDB event object.
799 // Return: MIstatus::success - Functionality succeeded.
800 // MIstatus::failure - Functionality failed.
804 CMICmnLLDBDebuggerHandleEvents::HandleProcessEventBroadcastBitStateChanged(const lldb::SBEvent &vEvent)
806 // Make sure the program hasn't been auto-restarted:
807 if (lldb::SBProcess::GetRestartedFromEvent(vEvent))
808 return MIstatus::success;
810 bool bOk = ChkForStateChanges();
811 bOk = bOk && GetProcessStdout();
812 bOk = bOk && GetProcessStderr();
814 return MIstatus::failure;
816 // Something changed in the process; get the event and report the process's current
817 // status and location
818 const lldb::StateType eEventState = lldb::SBProcess::GetStateFromEvent(vEvent);
819 if (eEventState == lldb::eStateInvalid)
820 return MIstatus::success;
822 lldb::SBProcess process = lldb::SBProcess::GetProcessFromEvent(vEvent);
823 if (!process.IsValid())
825 const CMIUtilString msg(CMIUtilString::Format(MIRSRC(IDS_LLDBOUTOFBAND_ERR_PROCESS_INVALID), "SBProcess",
826 "HandleProcessEventBroadcastBitStateChanged()"));
827 SetErrorDescription(msg);
828 return MIstatus::failure;
831 bool bShouldBrk = true;
832 const char *pEventType = "";
835 case lldb::eStateUnloaded:
836 pEventType = "eStateUnloaded";
838 case lldb::eStateConnected:
839 pEventType = "eStateConnected";
841 case lldb::eStateAttaching:
842 pEventType = "eStateAttaching";
844 case lldb::eStateLaunching:
845 pEventType = "eStateLaunching";
847 case lldb::eStateStopped:
848 pEventType = "eStateStopped";
849 bOk = HandleProcessEventStateStopped(vEvent, bShouldBrk);
852 case lldb::eStateCrashed:
853 case lldb::eStateSuspended:
854 pEventType = "eStateSuspended";
855 bOk = HandleProcessEventStateSuspended(vEvent);
857 case lldb::eStateRunning:
858 pEventType = "eStateRunning";
859 bOk = HandleProcessEventStateRunning();
861 case lldb::eStateStepping:
862 pEventType = "eStateStepping";
864 case lldb::eStateDetached:
865 pEventType = "eStateDetached";
867 case lldb::eStateExited:
868 // Don't exit from lldb-mi here. We should be able to re-run target.
869 pEventType = "eStateExited";
870 bOk = HandleProcessEventStateExited();
874 const CMIUtilString msg(CMIUtilString::Format(MIRSRC(IDS_LLDBOUTOFBAND_ERR_UNKNOWN_EVENT), "SBProcess BroadcastBitStateChanged",
875 (MIuint)eEventState));
876 SetErrorDescription(msg);
877 return MIstatus::failure;
881 // ToDo: Remove when finished coding application
882 m_pLog->WriteLog(CMIUtilString::Format("##### An SB Process event BroadcastBitStateChanged occurred: %s", pEventType));
887 //++ ------------------------------------------------------------------------------------
888 // Details: Asynchronous event handler for LLDB Process state suspended.
890 // Args: vEvent - (R) An LLDB event object.
891 // Return: MIstatus::success - Functionality succeeded.
892 // MIstatus::failure - Functionality failed.
896 CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStateSuspended(const lldb::SBEvent &vEvent)
898 bool bOk = MIstatus::success;
899 lldb::SBDebugger &rDebugger = CMICmnLLDBDebugSessionInfo::Instance().GetDebugger();
900 lldb::SBProcess sbProcess = CMICmnLLDBDebugSessionInfo::Instance().GetProcess();
901 lldb::SBTarget target = sbProcess.GetTarget();
902 if (rDebugger.GetSelectedTarget() == target)
904 if (!UpdateSelectedThread())
905 return MIstatus::failure;
907 lldb::SBCommandReturnObject result;
908 const lldb::ReturnStatus status = rDebugger.GetCommandInterpreter().HandleCommand("process status", result, false);
910 bOk = TextToStderr(result.GetError());
911 bOk = bOk && TextToStdout(result.GetOutput());
915 lldb::SBStream streamOut;
916 const MIuint nTargetIndex = rDebugger.GetIndexOfTarget(target);
917 if (nTargetIndex != UINT_MAX)
918 streamOut.Printf("Target %d: (", nTargetIndex);
920 streamOut.Printf("Target <unknown index>: (");
921 target.GetDescription(streamOut, lldb::eDescriptionLevelBrief);
922 streamOut.Printf(") stopped.\n");
923 bOk = TextToStdout(streamOut.GetData());
929 //++ ------------------------------------------------------------------------------------
930 // Details: Print to stdout MI formatted text to indicate process stopped.
932 // Args: vwrbShouldBrk - (W) True = Yes break, false = do not.
933 // Return: MIstatus::success - Functionality succeeded.
934 // MIstatus::failure - Functionality failed.
938 CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStateStopped(const lldb::SBEvent &vrEvent, bool &vwrbShouldBrk)
940 if (!UpdateSelectedThread())
941 return MIstatus::failure;
943 const char *pEventType = "";
944 bool bOk = MIstatus::success;
945 lldb::SBProcess sbProcess = CMICmnLLDBDebugSessionInfo::Instance().GetProcess();
946 const lldb::StopReason eStoppedReason = sbProcess.GetSelectedThread().GetStopReason();
947 switch (eStoppedReason)
949 case lldb::eStopReasonInvalid:
950 pEventType = "eStopReasonInvalid";
951 vwrbShouldBrk = false;
953 case lldb::eStopReasonNone:
954 pEventType = "eStopReasonNone";
956 case lldb::eStopReasonTrace:
957 pEventType = "eStopReasonTrace";
958 bOk = HandleProcessEventStopReasonTrace();
960 case lldb::eStopReasonBreakpoint:
961 pEventType = "eStopReasonBreakpoint";
962 bOk = HandleProcessEventStopReasonBreakpoint();
964 case lldb::eStopReasonWatchpoint:
965 pEventType = "eStopReasonWatchpoint";
967 case lldb::eStopReasonSignal:
968 pEventType = "eStopReasonSignal";
969 bOk = HandleProcessEventStopSignal(vrEvent);
971 case lldb::eStopReasonException:
972 pEventType = "eStopReasonException";
973 bOk = HandleProcessEventStopException();
975 case lldb::eStopReasonExec:
976 pEventType = "eStopReasonExec";
978 case lldb::eStopReasonPlanComplete:
979 pEventType = "eStopReasonPlanComplete";
980 bOk = HandleProcessEventStopReasonTrace();
982 case lldb::eStopReasonThreadExiting:
983 pEventType = "eStopReasonThreadExiting";
985 case lldb::eStopReasonInstrumentation:
986 pEventType = "eStopReasonInstrumentation";
990 // ToDo: Remove when finished coding application
991 m_pLog->WriteLog(CMIUtilString::Format("##### An SB Process event stop state occurred: %s", pEventType));
996 //++ ------------------------------------------------------------------------------------
997 // Details: Asynchronous event handler for LLDB Process stop signal.
999 // Args: vrEvent - (R) An LLDB broadcast event.
1000 // Return: MIstatus::success - Functionality succeeded.
1001 // MIstatus::failure - Functionality failed.
1005 CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStopSignal(const lldb::SBEvent &vrEvent)
1007 bool bOk = MIstatus::success;
1009 InitializeSignals ();
1010 lldb::SBProcess sbProcess = CMICmnLLDBDebugSessionInfo::Instance().GetProcess();
1011 const MIuint64 nStopReason = sbProcess.GetSelectedThread().GetStopReasonDataAtIndex(0);
1012 const bool bInterrupted = lldb::SBProcess::GetInterruptedFromEvent(vrEvent);
1013 if (nStopReason == m_SIGINT || (nStopReason == m_SIGSTOP && bInterrupted))
1015 // MI print "*stopped,reason=\"signal-received\",signal-name=\"SIGINT\",signal-meaning=\"Interrupt\",frame={%s},thread-id=\"%d\",stopped-threads=\"all\""
1016 const CMICmnMIValueConst miValueConst("signal-received");
1017 const CMICmnMIValueResult miValueResult("reason", miValueConst);
1018 CMICmnMIOutOfBandRecord miOutOfBandRecord(CMICmnMIOutOfBandRecord::eOutOfBand_Stopped, miValueResult);
1019 const CMICmnMIValueConst miValueConst2("SIGINT");
1020 const CMICmnMIValueResult miValueResult2("signal-name", miValueConst2);
1021 bOk = miOutOfBandRecord.Add(miValueResult2);
1022 const CMICmnMIValueConst miValueConst3("Interrupt");
1023 const CMICmnMIValueResult miValueResult3("signal-meaning", miValueConst3);
1024 bOk = bOk && miOutOfBandRecord.Add(miValueResult3);
1025 CMICmnMIValueTuple miValueTuple;
1026 bOk = bOk && MiHelpGetCurrentThreadFrame(miValueTuple);
1027 const CMICmnMIValueResult miValueResult4("frame", miValueTuple);
1028 bOk = bOk && miOutOfBandRecord.Add(miValueResult4);
1029 const CMIUtilString strThreadId(CMIUtilString::Format("%" PRIu32, sbProcess.GetSelectedThread().GetIndexID()));
1030 const CMICmnMIValueConst miValueConst5(strThreadId);
1031 const CMICmnMIValueResult miValueResult5("thread-id", miValueConst5);
1032 bOk = bOk && miOutOfBandRecord.Add(miValueResult5);
1033 const CMICmnMIValueConst miValueConst6("all");
1034 const CMICmnMIValueResult miValueResult6("stopped-threads", miValueConst6);
1035 bOk = bOk && miOutOfBandRecord.Add(miValueResult6);
1036 bOk = bOk && MiOutOfBandRecordToStdout(miOutOfBandRecord);
1037 bOk = bOk && CMICmnStreamStdout::WritePrompt();
1039 else if (nStopReason == m_SIGSTOP)
1041 // MI print "*stopped,reason=\"signal-received\",signal-name=\"SIGSTOP\",signal-meaning=\"Stop\",frame={%s},thread-id=\"%d\",stopped-threads=\"all\""
1042 const CMICmnMIValueConst miValueConst("signal-received");
1043 const CMICmnMIValueResult miValueResult("reason", miValueConst);
1044 CMICmnMIOutOfBandRecord miOutOfBandRecord(CMICmnMIOutOfBandRecord::eOutOfBand_Stopped, miValueResult);
1045 const CMICmnMIValueConst miValueConst2("SIGSTOP");
1046 const CMICmnMIValueResult miValueResult2("signal-name", miValueConst2);
1047 bOk = miOutOfBandRecord.Add(miValueResult2);
1048 const CMICmnMIValueConst miValueConst3("Stop");
1049 const CMICmnMIValueResult miValueResult3("signal-meaning", miValueConst3);
1050 bOk = bOk && miOutOfBandRecord.Add(miValueResult3);
1051 CMICmnMIValueTuple miValueTuple;
1052 bOk = bOk && MiHelpGetCurrentThreadFrame(miValueTuple);
1053 const CMICmnMIValueResult miValueResult4("frame", miValueTuple);
1054 bOk = bOk && miOutOfBandRecord.Add(miValueResult4);
1055 const CMIUtilString strThreadId(CMIUtilString::Format("%" PRIu32, sbProcess.GetSelectedThread().GetIndexID()));
1056 const CMICmnMIValueConst miValueConst5(strThreadId);
1057 const CMICmnMIValueResult miValueResult5("thread-id", miValueConst5);
1058 bOk = bOk && miOutOfBandRecord.Add(miValueResult5);
1059 const CMICmnMIValueConst miValueConst6("all");
1060 const CMICmnMIValueResult miValueResult6("stopped-threads", miValueConst6);
1061 bOk = bOk && miOutOfBandRecord.Add(miValueResult6);
1062 bOk = bOk && MiOutOfBandRecordToStdout(miOutOfBandRecord);
1063 bOk = bOk && CMICmnStreamStdout::WritePrompt();
1065 else if (nStopReason == m_SIGSEGV)
1067 // MI print "*stopped,reason=\"signal-received\",signal-name=\"SIGSEGV\",signal-meaning=\"Segmentation fault\",thread-id=\"%d\",frame={%s}"
1068 const CMICmnMIValueConst miValueConst("signal-received");
1069 const CMICmnMIValueResult miValueResult("reason", miValueConst);
1070 CMICmnMIOutOfBandRecord miOutOfBandRecord(CMICmnMIOutOfBandRecord::eOutOfBand_Stopped, miValueResult);
1071 const CMICmnMIValueConst miValueConst2("SIGSEGV");
1072 const CMICmnMIValueResult miValueResult2("signal-name", miValueConst2);
1073 bOk = miOutOfBandRecord.Add(miValueResult2);
1074 const CMICmnMIValueConst miValueConst3("Segmentation fault");
1075 const CMICmnMIValueResult miValueResult3("signal-meaning", miValueConst3);
1076 bOk = bOk && miOutOfBandRecord.Add(miValueResult3);
1077 CMICmnMIValueTuple miValueTuple;
1078 bOk = bOk && MiHelpGetCurrentThreadFrame(miValueTuple);
1079 const CMICmnMIValueResult miValueResult4("frame", miValueTuple);
1080 bOk = bOk && miOutOfBandRecord.Add(miValueResult4);
1081 const CMIUtilString strThreadId(CMIUtilString::Format("%d", sbProcess.GetSelectedThread().GetIndexID()));
1082 const CMICmnMIValueConst miValueConst5(strThreadId);
1083 const CMICmnMIValueResult miValueResult5("thread-id", miValueConst5);
1084 bOk = bOk && miOutOfBandRecord.Add(miValueResult5);
1085 bOk = bOk && MiOutOfBandRecordToStdout(miOutOfBandRecord);
1086 // Note no "(gdb)" output here
1088 else if (nStopReason == m_SIGTRAP)
1090 lldb::SBThread thread = sbProcess.GetSelectedThread();
1091 const MIuint nFrames = thread.GetNumFrames();
1094 lldb::SBFrame frame = thread.GetFrameAtIndex(0);
1095 const char *pFnName = frame.GetFunctionName();
1096 if (pFnName != nullptr)
1098 const CMIUtilString fnName = CMIUtilString(pFnName);
1099 static const CMIUtilString threadCloneFn = CMIUtilString("__pthread_clone");
1101 if (CMIUtilString::Compare(threadCloneFn, fnName))
1103 if (sbProcess.IsValid())
1104 sbProcess.Continue();
1111 // MI print "*stopped,reason=\"signal-received\",signal-name=\"%s\",thread-id=\"%d\",stopped-threads=\"all\""
1112 // MI print "*stopped,reason=\"signal-received\",signal=\"%d\",thread-id=\"%d\",stopped-threads=\"all\""
1113 const CMICmnMIValueConst miValueConst("signal-received");
1114 const CMICmnMIValueResult miValueResult("reason", miValueConst);
1115 CMICmnMIOutOfBandRecord miOutOfBandRecord(CMICmnMIOutOfBandRecord::eOutOfBand_Stopped, miValueResult);
1116 lldb::SBUnixSignals sbUnixSignals = sbProcess.GetUnixSignals();
1117 const char *pSignal = sbUnixSignals.GetSignalAsCString(nStopReason);
1120 const CMICmnMIValueConst miValueConst2(pSignal);
1121 const CMICmnMIValueResult miValueResult2("signal-name", miValueConst2);
1122 bOk = miOutOfBandRecord.Add(miValueResult2);
1126 const CMIUtilString strSignal(CMIUtilString::Format("%" PRIu64, nStopReason));
1127 const CMICmnMIValueConst miValueConst2(strSignal);
1128 const CMICmnMIValueResult miValueResult2("signal", miValueConst2);
1129 bOk = miOutOfBandRecord.Add(miValueResult2);
1131 const CMIUtilString strThreadId(CMIUtilString::Format("%d", sbProcess.GetSelectedThread().GetIndexID()));
1132 const CMICmnMIValueConst miValueConst3(strThreadId);
1133 const CMICmnMIValueResult miValueResult3("thread-id", miValueConst3);
1134 bOk = bOk && miOutOfBandRecord.Add(miValueResult3);
1135 const CMICmnMIValueConst miValueConst4("all");
1136 const CMICmnMIValueResult miValueResult4("stopped-threads", miValueConst4);
1137 bOk = bOk && miOutOfBandRecord.Add(miValueResult4);
1138 bOk = bOk && MiOutOfBandRecordToStdout(miOutOfBandRecord);
1139 bOk = bOk && CMICmnStreamStdout::WritePrompt();
1144 //++ ------------------------------------------------------------------------------------
1145 // Details: Asynchronous event handler for LLDB Process stop exception.
1148 // Return: MIstatus::success - Functional succeeded.
1149 // MIstatus::failure - Functional failed.
1153 CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStopException(void)
1155 const lldb::SBProcess sbProcess = CMICmnLLDBDebugSessionInfo::Instance().GetProcess();
1156 lldb::SBThread sbThread = sbProcess.GetSelectedThread();
1157 const size_t nStopDescriptionLen = sbThread.GetStopDescription(nullptr, 0);
1158 std::unique_ptr<char[]> apStopDescription(new char[nStopDescriptionLen]);
1159 sbThread.GetStopDescription(apStopDescription.get(), nStopDescriptionLen);
1161 // MI print "*stopped,reason=\"exception-received\",exception=\"%s\",thread-id=\"%d\",stopped-threads=\"all\""
1162 const CMICmnMIValueConst miValueConst("exception-received");
1163 const CMICmnMIValueResult miValueResult("reason", miValueConst);
1164 CMICmnMIOutOfBandRecord miOutOfBandRecord(CMICmnMIOutOfBandRecord::eOutOfBand_Stopped, miValueResult);
1165 const CMIUtilString strReason(apStopDescription.get());
1166 const CMICmnMIValueConst miValueConst2(strReason);
1167 const CMICmnMIValueResult miValueResult2("exception", miValueConst2);
1168 bool bOk = miOutOfBandRecord.Add(miValueResult2);
1169 const CMIUtilString strThreadId(CMIUtilString::Format("%d", sbThread.GetIndexID()));
1170 const CMICmnMIValueConst miValueConst3(strThreadId);
1171 const CMICmnMIValueResult miValueResult3("thread-id", miValueConst3);
1172 bOk = bOk && miOutOfBandRecord.Add(miValueResult3);
1173 const CMICmnMIValueConst miValueConst4("all");
1174 const CMICmnMIValueResult miValueResult4("stopped-threads", miValueConst4);
1175 bOk = bOk && miOutOfBandRecord.Add(miValueResult4);
1176 bOk = bOk && MiOutOfBandRecordToStdout(miOutOfBandRecord);
1177 bOk = bOk && CMICmnStreamStdout::WritePrompt();
1182 //++ ------------------------------------------------------------------------------------
1183 // Details: Form partial MI response in a MI value tuple object.
1185 // Args: vwrMiValueTuple - (W) MI value tuple object.
1186 // Return: MIstatus::success - Functionality succeeded.
1187 // MIstatus::failure - Functionality failed.
1191 CMICmnLLDBDebuggerHandleEvents::MiHelpGetCurrentThreadFrame(CMICmnMIValueTuple &vwrMiValueTuple)
1193 CMIUtilString strThreadFrame;
1194 lldb::SBProcess sbProcess = CMICmnLLDBDebugSessionInfo::Instance().GetProcess();
1195 lldb::SBThread thread = sbProcess.GetSelectedThread();
1196 const MIuint nFrame = thread.GetNumFrames();
1199 // MI print "addr=\"??\",func=\"??\",file=\"??\",fullname=\"??\",line=\"??\""
1200 const CMICmnMIValueConst miValueConst("??");
1201 const CMICmnMIValueResult miValueResult("addr", miValueConst);
1202 CMICmnMIValueTuple miValueTuple(miValueResult);
1203 const CMICmnMIValueResult miValueResult2("func", miValueConst);
1204 miValueTuple.Add(miValueResult2);
1205 const CMICmnMIValueResult miValueResult4("file", miValueConst);
1206 miValueTuple.Add(miValueResult4);
1207 const CMICmnMIValueResult miValueResult5("fullname", miValueConst);
1208 miValueTuple.Add(miValueResult5);
1209 const CMICmnMIValueResult miValueResult6("line", miValueConst);
1210 miValueTuple.Add(miValueResult6);
1212 vwrMiValueTuple = miValueTuple;
1214 return MIstatus::success;
1217 CMICmnMIValueTuple miValueTuple;
1218 if (!CMICmnLLDBDebugSessionInfo::Instance().MIResponseFormFrameInfo(thread, 0, CMICmnLLDBDebugSessionInfo::eFrameInfoFormat_NoArguments, miValueTuple))
1220 SetErrorDescription(CMIUtilString::Format(MIRSRC(IDS_LLDBOUTOFBAND_ERR_FORM_MI_RESPONSE), "MiHelpGetCurrentThreadFrame()"));
1221 return MIstatus::failure;
1224 vwrMiValueTuple = miValueTuple;
1226 return MIstatus::success;
1229 //++ ------------------------------------------------------------------------------------
1230 // Details: Asynchronous event handler for LLDB Process stop reason breakpoint.
1233 // Return: MIstatus::success - Functionality succeeded.
1234 // MIstatus::failure - Functionality failed.
1238 CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStopReasonBreakpoint(void)
1240 // CODETAG_DEBUG_SESSION_RUNNING_PROG_RECEIVED_SIGINT_PAUSE_PROGRAM
1241 if (!CMIDriver::Instance().SetDriverStateRunningNotDebugging())
1243 const CMIUtilString &rErrMsg(CMIDriver::Instance().GetErrorDescription());
1244 SetErrorDescription(CMIUtilString::Format(MIRSRC(IDS_LLDBOUTOFBAND_ERR_SETNEWDRIVERSTATE),
1245 "HandleProcessEventStopReasonBreakpoint()", rErrMsg.c_str()));
1246 return MIstatus::failure;
1249 lldb::SBProcess sbProcess = CMICmnLLDBDebugSessionInfo::Instance().GetProcess();
1250 const MIuint64 brkPtId = sbProcess.GetSelectedThread().GetStopReasonDataAtIndex(0);
1251 lldb::SBBreakpoint brkPt = CMICmnLLDBDebugSessionInfo::Instance().GetTarget().GetBreakpointAtIndex((MIuint)brkPtId);
1253 return MiStoppedAtBreakPoint(brkPtId, brkPt);
1256 //++ ------------------------------------------------------------------------------------
1257 // Details: Form the MI Out-of-band response for stopped reason on hitting a break point.
1259 // Args: vBrkPtId - (R) The LLDB break point's ID
1260 // vBrkPt - (R) THe LLDB break point object.
1261 // Return: MIstatus::success - Functionality succeeded.
1262 // MIstatus::failure - Functionality failed.
1266 CMICmnLLDBDebuggerHandleEvents::MiStoppedAtBreakPoint(const MIuint64 vBrkPtId, const lldb::SBBreakpoint &vBrkPt)
1268 bool bOk = MIstatus::success;
1270 lldb::SBProcess sbProcess = CMICmnLLDBDebugSessionInfo::Instance().GetProcess();
1271 lldb::SBThread thread = sbProcess.GetSelectedThread();
1272 const MIuint nFrame = thread.GetNumFrames();
1275 // MI print "*stopped,reason=\"breakpoint-hit\",disp=\"del\",bkptno=\"%d\",frame={},thread-id=\"%d\",stopped-threads=\"all\""
1276 const CMICmnMIValueConst miValueConst("breakpoint-hit");
1277 const CMICmnMIValueResult miValueResult("reason", miValueConst);
1278 CMICmnMIOutOfBandRecord miOutOfBandRecord(CMICmnMIOutOfBandRecord::eOutOfBand_Stopped, miValueResult);
1279 const CMICmnMIValueConst miValueConst2("del");
1280 const CMICmnMIValueResult miValueResult2("disp", miValueConst2);
1281 bOk = miOutOfBandRecord.Add(miValueResult2);
1282 const CMIUtilString strBkp(CMIUtilString::Format("%d", vBrkPtId));
1283 const CMICmnMIValueConst miValueConst3(strBkp);
1284 CMICmnMIValueResult miValueResult3("bkptno", miValueConst3);
1285 bOk = bOk && miOutOfBandRecord.Add(miValueResult3);
1286 const CMICmnMIValueConst miValueConst4("{}");
1287 const CMICmnMIValueResult miValueResult4("frame", miValueConst4);
1288 bOk = bOk && miOutOfBandRecord.Add(miValueResult4);
1289 const CMIUtilString strThreadId(CMIUtilString::Format("%d", vBrkPt.GetThreadIndex()));
1290 const CMICmnMIValueConst miValueConst5(strThreadId);
1291 const CMICmnMIValueResult miValueResult5("thread-id", miValueConst5);
1292 bOk = bOk && miOutOfBandRecord.Add(miValueResult5);
1293 const CMICmnMIValueConst miValueConst6("all");
1294 const CMICmnMIValueResult miValueResult6("stopped-threads", miValueConst6);
1295 bOk = bOk && miOutOfBandRecord.Add(miValueResult6);
1296 bOk = bOk && MiOutOfBandRecordToStdout(miOutOfBandRecord);
1297 bOk = bOk && CMICmnStreamStdout::WritePrompt();
1301 CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
1304 // "*stopped,reason=\"breakpoint-hit\",disp=\"del\",bkptno=\"%d\",frame={addr=\"0x%016" PRIx64 "\",func=\"%s\",args=[],file=\"%s\",fullname=\"%s\",line=\"%d\"},thread-id=\"%d\",stopped-threads=\"all\""
1305 const CMICmnMIValueConst miValueConst("breakpoint-hit");
1306 const CMICmnMIValueResult miValueResult("reason", miValueConst);
1307 CMICmnMIOutOfBandRecord miOutOfBandRecord(CMICmnMIOutOfBandRecord::eOutOfBand_Stopped, miValueResult);
1308 const CMICmnMIValueConst miValueConstA("del");
1309 const CMICmnMIValueResult miValueResultA("disp", miValueConstA);
1310 bOk = miOutOfBandRecord.Add(miValueResultA);
1311 const CMIUtilString strBkp(CMIUtilString::Format("%d", vBrkPtId));
1312 const CMICmnMIValueConst miValueConstB(strBkp);
1313 CMICmnMIValueResult miValueResultB("bkptno", miValueConstB);
1314 bOk = bOk && miOutOfBandRecord.Add(miValueResultB);
1316 // frame={addr=\"0x%016" PRIx64 "\",func=\"%s\",args=[],file=\"%s\",fullname=\"%s\",line=\"%d\"}
1319 CMICmnMIValueTuple miValueTuple;
1320 bOk = bOk && rSessionInfo.MIResponseFormFrameInfo(thread, 0, CMICmnLLDBDebugSessionInfo::eFrameInfoFormat_AllArguments, miValueTuple);
1321 const CMICmnMIValueResult miValueResult8("frame", miValueTuple);
1322 bOk = bOk && miOutOfBandRecord.Add(miValueResult8);
1325 // Add to MI thread-id=\"%d\",stopped-threads=\"all\"
1328 const CMIUtilString strThreadId(CMIUtilString::Format("%d", thread.GetIndexID()));
1329 const CMICmnMIValueConst miValueConst8(strThreadId);
1330 const CMICmnMIValueResult miValueResult8("thread-id", miValueConst8);
1331 bOk = miOutOfBandRecord.Add(miValueResult8);
1335 const CMICmnMIValueConst miValueConst9("all");
1336 const CMICmnMIValueResult miValueResult9("stopped-threads", miValueConst9);
1337 bOk = miOutOfBandRecord.Add(miValueResult9);
1338 bOk = MiOutOfBandRecordToStdout(miOutOfBandRecord);
1339 bOk = bOk && CMICmnStreamStdout::WritePrompt();
1342 return MIstatus::success;
1345 //++ ------------------------------------------------------------------------------------
1346 // Details: Asynchronous event handler for LLDB Process stop reason trace.
1349 // Return: MIstatus::success - Functionality succeeded.
1350 // MIstatus::failure - Functionality failed.
1354 CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStopReasonTrace(void)
1357 lldb::SBProcess sbProcess = CMICmnLLDBDebugSessionInfo::Instance().GetProcess();
1358 lldb::SBThread thread = sbProcess.GetSelectedThread();
1359 const MIuint nFrame = thread.GetNumFrames();
1362 // MI print "*stopped,reason=\"trace\",stopped-threads=\"all\""
1363 const CMICmnMIValueConst miValueConst("trace");
1364 const CMICmnMIValueResult miValueResult("reason", miValueConst);
1365 CMICmnMIOutOfBandRecord miOutOfBandRecord(CMICmnMIOutOfBandRecord::eOutOfBand_Stopped, miValueResult);
1366 const CMICmnMIValueConst miValueConst2("all");
1367 const CMICmnMIValueResult miValueResult2("stopped-threads", miValueConst2);
1368 bOk = miOutOfBandRecord.Add(miValueResult2);
1369 bOk = MiOutOfBandRecordToStdout(miOutOfBandRecord);
1370 bOk = bOk && CMICmnStreamStdout::WritePrompt();
1374 CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
1377 // "*stopped,reason=\"end-stepping-range\",frame={addr=\"0x%016" PRIx64 "\",func=\"%s\",args=[\"%s\"],file=\"%s\",fullname=\"%s\",line=\"%d\"},thread-id=\"%d\",stopped-threads=\"all\""
1380 CMICmnMIValueTuple miValueTuple;
1381 if (!rSessionInfo.MIResponseFormFrameInfo(thread, 0, CMICmnLLDBDebugSessionInfo::eFrameInfoFormat_AllArguments, miValueTuple))
1382 return MIstatus::failure;
1384 const CMICmnMIValueConst miValueConst("end-stepping-range");
1385 const CMICmnMIValueResult miValueResult("reason", miValueConst);
1386 CMICmnMIOutOfBandRecord miOutOfBandRecord(CMICmnMIOutOfBandRecord::eOutOfBand_Stopped, miValueResult);
1387 const CMICmnMIValueResult miValueResult2("frame", miValueTuple);
1388 bOk = miOutOfBandRecord.Add(miValueResult2);
1390 // Add to MI thread-id=\"%d\",stopped-threads=\"all\"
1393 const CMIUtilString strThreadId(CMIUtilString::Format("%d", thread.GetIndexID()));
1394 const CMICmnMIValueConst miValueConst8(strThreadId);
1395 const CMICmnMIValueResult miValueResult8("thread-id", miValueConst8);
1396 bOk = miOutOfBandRecord.Add(miValueResult8);
1400 const CMICmnMIValueConst miValueConst9("all");
1401 const CMICmnMIValueResult miValueResult9("stopped-threads", miValueConst9);
1402 bOk = miOutOfBandRecord.Add(miValueResult9);
1403 bOk = MiOutOfBandRecordToStdout(miOutOfBandRecord);
1404 bOk = bOk && CMICmnStreamStdout::WritePrompt();
1410 //++ ------------------------------------------------------------------------------------
1411 // Details: Asynchronous function update selected thread.
1414 // Return: MIstatus::success - Functionality succeeded.
1415 // MIstatus::failure - Functionality failed.
1419 CMICmnLLDBDebuggerHandleEvents::UpdateSelectedThread(void)
1421 lldb::SBProcess process = CMICmnLLDBDebugSessionInfo::Instance().GetDebugger().GetSelectedTarget().GetProcess();
1422 if (!process.IsValid())
1423 return MIstatus::success;
1425 lldb::SBThread currentThread = process.GetSelectedThread();
1426 lldb::SBThread thread;
1427 const lldb::StopReason eCurrentThreadStoppedReason = currentThread.GetStopReason();
1428 if (!currentThread.IsValid() || (eCurrentThreadStoppedReason == lldb::eStopReasonInvalid) ||
1429 (eCurrentThreadStoppedReason == lldb::eStopReasonNone))
1431 // Prefer a thread that has just completed its plan over another thread as current thread
1432 lldb::SBThread planThread;
1433 lldb::SBThread otherThread;
1434 const size_t nThread = process.GetNumThreads();
1435 for (MIuint i = 0; i < nThread; i++)
1437 // GetThreadAtIndex() uses a base 0 index
1438 // GetThreadByIndexID() uses a base 1 index
1439 thread = process.GetThreadAtIndex(i);
1440 const lldb::StopReason eThreadStopReason = thread.GetStopReason();
1441 switch (eThreadStopReason)
1443 case lldb::eStopReasonTrace:
1444 case lldb::eStopReasonBreakpoint:
1445 case lldb::eStopReasonWatchpoint:
1446 case lldb::eStopReasonSignal:
1447 case lldb::eStopReasonException:
1448 if (!otherThread.IsValid())
1449 otherThread = thread;
1451 case lldb::eStopReasonPlanComplete:
1452 if (!planThread.IsValid())
1453 planThread = thread;
1455 case lldb::eStopReasonInvalid:
1456 case lldb::eStopReasonNone:
1461 if (planThread.IsValid())
1462 process.SetSelectedThread(planThread);
1463 else if (otherThread.IsValid())
1464 process.SetSelectedThread(otherThread);
1467 if (currentThread.IsValid())
1468 thread = currentThread;
1470 thread = process.GetThreadAtIndex(0);
1472 if (thread.IsValid())
1473 process.SetSelectedThread(thread);
1475 } // if( !currentThread.IsValid() || (eCurrentThreadStoppedReason == lldb::eStopReasonInvalid) || (eCurrentThreadStoppedReason ==
1476 // lldb::eStopReasonNone) )
1478 return MIstatus::success;
1481 //++ ------------------------------------------------------------------------------------
1482 // Details: Print to stdout "*running,thread-id=\"all\"", "(gdb)".
1485 // Return: MIstatus::success - Functionality succeeded.
1486 // MIstatus::failure - Functionality failed.
1490 CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStateRunning(void)
1492 CMICmnMIValueConst miValueConst("all");
1493 CMICmnMIValueResult miValueResult("thread-id", miValueConst);
1494 CMICmnMIOutOfBandRecord miOutOfBandRecord(CMICmnMIOutOfBandRecord::eOutOfBand_Running, miValueResult);
1495 bool bOk = MiOutOfBandRecordToStdout(miOutOfBandRecord);
1496 bOk = bOk && CMICmnStreamStdout::WritePrompt();
1501 //++ ------------------------------------------------------------------------------------
1502 // Details: Print to stdout "=thread-exited,id=\"%ld\",group-id=\"i1\"",
1503 // "=thread-group-exited,id=\"i1\",exit-code=\"0\""),
1504 // "*stopped,reason=\"exited-normally\"",
1508 // Return: MIstatus::success - Functionality succeeded.
1509 // MIstatus::failure - Functionality failed.
1513 CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStateExited(void)
1515 const CMIUtilString strId(CMIUtilString::Format("%ld", 1));
1516 CMICmnMIValueConst miValueConst(strId);
1517 CMICmnMIValueResult miValueResult("id", miValueConst);
1518 CMICmnMIOutOfBandRecord miOutOfBandRecord(CMICmnMIOutOfBandRecord::eOutOfBand_ThreadExited, miValueResult);
1519 CMICmnMIValueConst miValueConst2("i1");
1520 CMICmnMIValueResult miValueResult2("group-id", miValueConst2);
1521 bool bOk = miOutOfBandRecord.Add(miValueResult2);
1522 bOk = bOk && MiOutOfBandRecordToStdout(miOutOfBandRecord);
1525 CMICmnMIValueConst miValueConst3("i1");
1526 CMICmnMIValueResult miValueResult3("id", miValueConst3);
1527 CMICmnMIOutOfBandRecord miOutOfBandRecord2(CMICmnMIOutOfBandRecord::eOutOfBand_ThreadGroupExited, miValueResult3);
1528 CMICmnMIValueConst miValueConst2("0");
1529 CMICmnMIValueResult miValueResult2("exit-code", miValueConst2);
1530 bOk = miOutOfBandRecord2.Add(miValueResult2);
1531 bOk = bOk && MiOutOfBandRecordToStdout(miOutOfBandRecord2);
1535 CMICmnMIValueConst miValueConst4("exited-normally");
1536 CMICmnMIValueResult miValueResult4("reason", miValueConst4);
1537 CMICmnMIOutOfBandRecord miOutOfBandRecord3(CMICmnMIOutOfBandRecord::eOutOfBand_Stopped, miValueResult4);
1538 bOk = MiOutOfBandRecordToStdout(miOutOfBandRecord3);
1540 bOk = bOk && CMICmnStreamStdout::WritePrompt();
1545 //++ ------------------------------------------------------------------------------------
1546 // Details: Drain all stdout so we don't see any output come after we print our prompts.
1547 // The process has stuff waiting for stdout; get it and write it out to the
1548 // appropriate place.
1551 // Return: MIstatus::success - Functionality succeeded.
1552 // MIstatus::failure - Functionality failed.
1556 CMICmnLLDBDebuggerHandleEvents::GetProcessStdout(void)
1559 std::unique_ptr<char[]> apStdoutBuffer(new char[1024]);
1560 lldb::SBProcess process = CMICmnLLDBDebugSessionInfo::Instance().GetDebugger().GetSelectedTarget().GetProcess();
1563 const size_t nBytes = process.GetSTDOUT(apStdoutBuffer.get(), 1024);
1564 text.append(apStdoutBuffer.get(), nBytes);
1568 const size_t nNewLine = text.find('\n');
1569 if (nNewLine == std::string::npos)
1572 const CMIUtilString line(text.substr(0, nNewLine + 1).c_str());
1573 text.erase(0, nNewLine + 1);
1574 const bool bEscapeQuotes(true);
1575 CMICmnMIValueConst miValueConst(line.Escape(bEscapeQuotes));
1576 CMICmnMIOutOfBandRecord miOutOfBandRecord(CMICmnMIOutOfBandRecord::eOutOfBand_TargetStreamOutput, miValueConst);
1577 const bool bOk = MiOutOfBandRecordToStdout(miOutOfBandRecord);
1579 return MIstatus::failure;
1586 const bool bEscapeQuotes(true);
1587 CMICmnMIValueConst miValueConst(text.Escape(bEscapeQuotes));
1588 CMICmnMIOutOfBandRecord miOutOfBandRecord(CMICmnMIOutOfBandRecord::eOutOfBand_TargetStreamOutput, miValueConst);
1589 return MiOutOfBandRecordToStdout(miOutOfBandRecord);
1595 return MIstatus::success;
1598 //++ ------------------------------------------------------------------------------------
1599 // Details: Drain all stderr so we don't see any output come after we print our prompts.
1600 // The process has stuff waiting for stderr; get it and write it out to the
1601 // appropriate place.
1604 // Return: MIstatus::success - Functionality succeeded.
1605 // MIstatus::failure - Functionality failed.
1609 CMICmnLLDBDebuggerHandleEvents::GetProcessStderr(void)
1612 std::unique_ptr<char[]> apStderrBuffer(new char[1024]);
1613 lldb::SBProcess process = CMICmnLLDBDebugSessionInfo::Instance().GetDebugger().GetSelectedTarget().GetProcess();
1616 const size_t nBytes = process.GetSTDERR(apStderrBuffer.get(), 1024);
1617 text.append(apStderrBuffer.get(), nBytes);
1621 const size_t nNewLine = text.find('\n');
1622 if (nNewLine == std::string::npos)
1625 const CMIUtilString line(text.substr(0, nNewLine + 1).c_str());
1626 const bool bEscapeQuotes(true);
1627 CMICmnMIValueConst miValueConst(line.Escape(bEscapeQuotes));
1628 CMICmnMIOutOfBandRecord miOutOfBandRecord(CMICmnMIOutOfBandRecord::eOutOfBand_TargetStreamOutput, miValueConst);
1629 const bool bOk = MiOutOfBandRecordToStdout(miOutOfBandRecord);
1631 return MIstatus::failure;
1638 const bool bEscapeQuotes(true);
1639 CMICmnMIValueConst miValueConst(text.Escape(bEscapeQuotes));
1640 CMICmnMIOutOfBandRecord miOutOfBandRecord(CMICmnMIOutOfBandRecord::eOutOfBand_TargetStreamOutput, miValueConst);
1641 return MiOutOfBandRecordToStdout(miOutOfBandRecord);
1647 return MIstatus::success;
1650 //++ ------------------------------------------------------------------------------------
1651 // Details: Asynchronous event function check for state changes.
1654 // Return: MIstatus::success - Functionality succeeded.
1655 // MIstatus::failure - Functionality failed.
1659 CMICmnLLDBDebuggerHandleEvents::ChkForStateChanges(void)
1661 CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
1662 lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
1663 if (!sbProcess.IsValid())
1664 return MIstatus::success;
1666 // Check for created threads
1667 const MIuint nThread = sbProcess.GetNumThreads();
1668 for (MIuint i = 0; i < nThread; i++)
1670 // GetThreadAtIndex() uses a base 0 index
1671 // GetThreadByIndexID() uses a base 1 index
1672 lldb::SBThread thread = sbProcess.GetThreadAtIndex(i);
1673 if (!thread.IsValid())
1676 const MIuint threadIndexID = thread.GetIndexID();
1677 const bool bFound = std::find(rSessionInfo.m_vecActiveThreadId.cbegin(), rSessionInfo.m_vecActiveThreadId.cend(), threadIndexID) != rSessionInfo.m_vecActiveThreadId.end();
1680 rSessionInfo.m_vecActiveThreadId.push_back(threadIndexID);
1682 // Form MI "=thread-created,id=\"%d\",group-id=\"i1\""
1683 const CMIUtilString strValue(CMIUtilString::Format("%d", threadIndexID));
1684 const CMICmnMIValueConst miValueConst(strValue);
1685 const CMICmnMIValueResult miValueResult("id", miValueConst);
1686 CMICmnMIOutOfBandRecord miOutOfBand(CMICmnMIOutOfBandRecord::eOutOfBand_ThreadCreated, miValueResult);
1687 const CMICmnMIValueConst miValueConst2("i1");
1688 const CMICmnMIValueResult miValueResult2("group-id", miValueConst2);
1689 bool bOk = miOutOfBand.Add(miValueResult2);
1690 bOk = bOk && MiOutOfBandRecordToStdout(miOutOfBand);
1692 return MIstatus::failure;
1696 lldb::SBThread currentThread = sbProcess.GetSelectedThread();
1697 if (currentThread.IsValid())
1699 const MIuint currentThreadIndexID = currentThread.GetIndexID();
1700 if (rSessionInfo.m_currentSelectedThread != currentThreadIndexID)
1702 rSessionInfo.m_currentSelectedThread = currentThreadIndexID;
1704 // Form MI "=thread-selected,id=\"%d\""
1705 const CMIUtilString strValue(CMIUtilString::Format("%d", currentThreadIndexID));
1706 const CMICmnMIValueConst miValueConst(strValue);
1707 const CMICmnMIValueResult miValueResult("id", miValueConst);
1708 CMICmnMIOutOfBandRecord miOutOfBand(CMICmnMIOutOfBandRecord::eOutOfBand_ThreadSelected, miValueResult);
1709 if (!MiOutOfBandRecordToStdout(miOutOfBand))
1710 return MIstatus::failure;
1714 // Check for invalid (removed) threads
1715 CMICmnLLDBDebugSessionInfo::VecActiveThreadId_t::iterator it = rSessionInfo.m_vecActiveThreadId.begin();
1716 while (it != rSessionInfo.m_vecActiveThreadId.end())
1718 const MIuint threadIndexID = *it;
1719 lldb::SBThread thread = sbProcess.GetThreadByIndexID(threadIndexID);
1720 if (!thread.IsValid())
1722 // Form MI "=thread-exited,id=\"%ld\",group-id=\"i1\""
1723 const CMIUtilString strValue(CMIUtilString::Format("%ld", threadIndexID));
1724 const CMICmnMIValueConst miValueConst(strValue);
1725 const CMICmnMIValueResult miValueResult("id", miValueConst);
1726 CMICmnMIOutOfBandRecord miOutOfBand(CMICmnMIOutOfBandRecord::eOutOfBand_ThreadExited, miValueResult);
1727 const CMICmnMIValueConst miValueConst2("i1");
1728 const CMICmnMIValueResult miValueResult2("group-id", miValueConst2);
1729 bool bOk = miOutOfBand.Add(miValueResult2);
1730 bOk = bOk && MiOutOfBandRecordToStdout(miOutOfBand);
1732 return MIstatus::failure;
1734 // Remove current thread from cache and get next
1735 it = rSessionInfo.m_vecActiveThreadId.erase(it);
1742 return CMICmnStreamStdout::WritePrompt();
1745 //++ ------------------------------------------------------------------------------------
1746 // Details: Take a fully formed MI result record and send to the stdout stream.
1747 // Also output to the MI Log file.
1749 // Args: vrMiResultRecord - (R) MI result record object.
1750 // Return: MIstatus::success - Functionality succeeded.
1751 // MIstatus::failure - Functionality failed.
1755 CMICmnLLDBDebuggerHandleEvents::MiResultRecordToStdout(const CMICmnMIResultRecord &vrMiResultRecord)
1757 return TextToStdout(vrMiResultRecord.GetString());
1760 //++ ------------------------------------------------------------------------------------
1761 // Details: Take a fully formed MI Out-of-band record and send to the stdout stream.
1762 // Also output to the MI Log file.
1764 // Args: vrMiOutOfBandRecord - (R) MI Out-of-band record object.
1765 // Return: MIstatus::success - Functionality succeeded.
1766 // MIstatus::failure - Functionality failed.
1770 CMICmnLLDBDebuggerHandleEvents::MiOutOfBandRecordToStdout(const CMICmnMIOutOfBandRecord &vrMiOutOfBandRecord)
1772 return TextToStdout(vrMiOutOfBandRecord.GetString());
1775 //++ ------------------------------------------------------------------------------------
1776 // Details: Take a text data and send to the stdout stream. Also output to the MI Log
1779 // Args: vrTxt - (R) Text.
1780 // Return: MIstatus::success - Functionality succeeded.
1781 // MIstatus::failure - Functionality failed.
1785 CMICmnLLDBDebuggerHandleEvents::TextToStdout(const CMIUtilString &vrTxt)
1787 return CMICmnStreamStdout::TextToStdout(vrTxt);
1790 //++ ------------------------------------------------------------------------------------
1791 // Details: Take a text data and send to the stderr stream. Also output to the MI Log
1794 // Args: vrTxt - (R) Text.
1795 // Return: MIstatus::success - Functionality succeeded.
1796 // MIstatus::failure - Functionality failed.
1800 CMICmnLLDBDebuggerHandleEvents::TextToStderr(const CMIUtilString &vrTxt)
1802 return CMICmnStreamStderr::TextToStderr(vrTxt);
1805 //++ ------------------------------------------------------------------------------------
1806 // Details: Initialize the member variables with the signal values in this process
1814 CMICmnLLDBDebuggerHandleEvents::InitializeSignals()
1816 if (!m_bSignalsInitialized)
1818 lldb::SBProcess sbProcess = CMICmnLLDBDebugSessionInfo::Instance().GetProcess();
1819 if (sbProcess.IsValid())
1821 lldb::SBUnixSignals unix_signals = sbProcess.GetUnixSignals();
1822 m_SIGINT = unix_signals.GetSignalNumberFromName("SIGINT");
1823 m_SIGSTOP = unix_signals.GetSignalNumberFromName("SIGSTOP");
1824 m_SIGSEGV = unix_signals.GetSignalNumberFromName("SIGSEGV");
1825 m_SIGTRAP = unix_signals.GetSignalNumberFromName("SIGTRAP");
1826 m_bSignalsInitialized = true;