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/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 #include "llvm/Support/Compiler.h"
29 #include "MICmnLLDBDebugSessionInfo.h"
30 #include "MICmnLLDBDebugger.h"
31 #include "MICmnLLDBDebuggerHandleEvents.h"
33 #include "MICmnMIOutOfBandRecord.h"
34 #include "MICmnMIResultRecord.h"
35 #include "MICmnMIValueConst.h"
36 #include "MICmnMIValueList.h"
37 #include "MICmnResources.h"
38 #include "MICmnStreamStderr.h"
39 #include "MICmnStreamStdout.h"
41 #include "MIUtilDebug.h"
47 //------------------------------------------------------------------------------------
48 // Details: CMICmnLLDBDebuggerHandleEvents constructor.
54 CMICmnLLDBDebuggerHandleEvents::CMICmnLLDBDebuggerHandleEvents() {}
57 //------------------------------------------------------------------------------------
58 // Details: CMICmnLLDBDebuggerHandleEvents destructor.
64 CMICmnLLDBDebuggerHandleEvents::~CMICmnLLDBDebuggerHandleEvents() {
69 //------------------------------------------------------------------------------------
70 // Details: Initialize resources for *this broadcaster object.
73 // Return: MIstatus::success - Functionality succeeded.
74 // MIstatus::failure - Functionality failed.
77 bool CMICmnLLDBDebuggerHandleEvents::Initialize() {
78 m_clientUsageRefCnt++;
81 return MIstatus::success;
83 m_bInitialized = MIstatus::success;
84 m_bSignalsInitialized = false;
90 return m_bInitialized;
94 //------------------------------------------------------------------------------------
95 // Details: Release resources for *this broadcaster object.
98 // Return: MIstatus::success - Functionality succeeded.
99 // MIstatus::failure - Functionality failed.
102 bool CMICmnLLDBDebuggerHandleEvents::Shutdown() {
103 if (--m_clientUsageRefCnt > 0)
104 return MIstatus::success;
107 return MIstatus::success;
109 m_bInitialized = false;
111 return MIstatus::success;
115 //------------------------------------------------------------------------------------
116 // Details: Interpret the event object to ascertain the action to take or
118 // to form and put in a MI Out-of-band record object which is given to
121 // Args: vEvent - (R) An LLDB broadcast event.
122 // vrbHandledEvent - (W) True - event handled, false = not handled.
123 // Return: MIstatus::success - Functionality succeeded.
124 // MIstatus::failure - Functionality failed.
127 bool CMICmnLLDBDebuggerHandleEvents::HandleEvent(const lldb::SBEvent &vEvent,
128 bool &vrbHandledEvent) {
129 bool bOk = MIstatus::success;
130 vrbHandledEvent = false;
132 if (lldb::SBProcess::EventIsProcessEvent(vEvent)) {
133 vrbHandledEvent = true;
134 bOk = HandleEventSBProcess(vEvent);
135 } else if (lldb::SBBreakpoint::EventIsBreakpointEvent(vEvent)) {
136 vrbHandledEvent = true;
137 bOk = HandleEventSBBreakPoint(vEvent);
138 } else if (lldb::SBThread::EventIsThreadEvent(vEvent)) {
139 vrbHandledEvent = true;
140 bOk = HandleEventSBThread(vEvent);
141 } else if (lldb::SBTarget::EventIsTargetEvent(vEvent)) {
142 vrbHandledEvent = true;
143 bOk = HandleEventSBTarget(vEvent);
144 } else if (lldb::SBCommandInterpreter::EventIsCommandInterpreterEvent(
146 vrbHandledEvent = true;
147 bOk = HandleEventSBCommandInterpreter(vEvent);
154 //------------------------------------------------------------------------------------
155 // Details: Handle a LLDB SBProcess event.
157 // Args: vEvent - (R) An LLDB broadcast event.
158 // Return: MIstatus::success - Functionality succeeded.
159 // MIstatus::failure - Functionality failed.
162 bool CMICmnLLDBDebuggerHandleEvents::HandleEventSBProcess(
163 const lldb::SBEvent &vEvent) {
164 bool bOk = MIstatus::success;
166 const char *pEventType = "";
167 const MIuint nEventType = vEvent.GetType();
168 switch (nEventType) {
169 case lldb::SBProcess::eBroadcastBitInterrupt:
170 pEventType = "eBroadcastBitInterrupt";
172 case lldb::SBProcess::eBroadcastBitProfileData:
173 pEventType = "eBroadcastBitProfileData";
175 case lldb::SBProcess::eBroadcastBitStructuredData:
176 pEventType = "eBroadcastBitStructuredData";
178 case lldb::SBProcess::eBroadcastBitStateChanged:
179 pEventType = "eBroadcastBitStateChanged";
180 bOk = HandleProcessEventBroadcastBitStateChanged(vEvent);
182 case lldb::SBProcess::eBroadcastBitSTDERR:
183 pEventType = "eBroadcastBitSTDERR";
184 bOk = GetProcessStderr();
186 case lldb::SBProcess::eBroadcastBitSTDOUT:
187 pEventType = "eBroadcastBitSTDOUT";
188 bOk = GetProcessStdout();
191 const CMIUtilString msg(
192 CMIUtilString::Format(MIRSRC(IDS_LLDBOUTOFBAND_ERR_UNKNOWN_EVENT),
193 "SBProcess", (MIuint)nEventType));
194 SetErrorDescription(msg);
195 return MIstatus::failure;
198 m_pLog->WriteLog(CMIUtilString::Format(
199 "##### An SB Process event occurred: %s", pEventType));
205 //------------------------------------------------------------------------------------
206 // Details: Handle a LLDB SBBreakpoint event.
208 // Args: vEvent - (R) An LLDB broadcast event.
209 // Return: MIstatus::success - Functionality succeeded.
210 // MIstatus::failure - Functionality failed.
213 bool CMICmnLLDBDebuggerHandleEvents::HandleEventSBBreakPoint(
214 const lldb::SBEvent &vEvent) {
215 bool bOk = MIstatus::success;
217 const char *pEventType = "";
218 const lldb::BreakpointEventType eEvent =
219 lldb::SBBreakpoint::GetBreakpointEventTypeFromEvent(vEvent);
221 case lldb::eBreakpointEventTypeThreadChanged:
222 pEventType = "eBreakpointEventTypeThreadChanged";
224 case lldb::eBreakpointEventTypeLocationsRemoved:
225 pEventType = "eBreakpointEventTypeLocationsRemoved";
227 case lldb::eBreakpointEventTypeInvalidType:
228 pEventType = "eBreakpointEventTypeInvalidType";
230 case lldb::eBreakpointEventTypeLocationsAdded:
231 pEventType = "eBreakpointEventTypeLocationsAdded";
232 bOk = HandleEventSBBreakpointLocationsAdded(vEvent);
234 case lldb::eBreakpointEventTypeAdded:
235 pEventType = "eBreakpointEventTypeAdded";
236 bOk = HandleEventSBBreakpointAdded(vEvent);
238 case lldb::eBreakpointEventTypeRemoved:
239 pEventType = "eBreakpointEventTypeRemoved";
240 bOk = HandleEventSBBreakpointCmn(vEvent);
242 case lldb::eBreakpointEventTypeLocationsResolved:
243 pEventType = "eBreakpointEventTypeLocationsResolved";
244 bOk = HandleEventSBBreakpointCmn(vEvent);
246 case lldb::eBreakpointEventTypeEnabled:
247 pEventType = "eBreakpointEventTypeEnabled";
248 bOk = HandleEventSBBreakpointCmn(vEvent);
250 case lldb::eBreakpointEventTypeDisabled:
251 pEventType = "eBreakpointEventTypeDisabled";
252 bOk = HandleEventSBBreakpointCmn(vEvent);
254 case lldb::eBreakpointEventTypeCommandChanged:
255 pEventType = "eBreakpointEventTypeCommandChanged";
256 bOk = HandleEventSBBreakpointCmn(vEvent);
258 case lldb::eBreakpointEventTypeConditionChanged:
259 pEventType = "eBreakpointEventTypeConditionChanged";
260 bOk = HandleEventSBBreakpointCmn(vEvent);
262 case lldb::eBreakpointEventTypeIgnoreChanged:
263 pEventType = "eBreakpointEventTypeIgnoreChanged";
264 bOk = HandleEventSBBreakpointCmn(vEvent);
266 case lldb::eBreakpointEventTypeAutoContinueChanged:
267 pEventType = "eBreakpointEventTypeAutoContinueChanged";
268 bOk = HandleEventSBBreakpointCmn(vEvent);
271 m_pLog->WriteLog(CMIUtilString::Format(
272 "##### An SB Breakpoint event occurred: %s", pEventType));
278 //------------------------------------------------------------------------------------
279 // Details: Handle a LLDB SBBreakpoint event.
281 // Args: vEvent - (R) An LLDB broadcast event.
282 // Return: MIstatus::success - Functionality succeeded.
283 // MIstatus::failure - Functionality failed.
286 bool CMICmnLLDBDebuggerHandleEvents::HandleEventSBBreakpointLocationsAdded(
287 const lldb::SBEvent &vEvent) {
289 lldb::SBBreakpoint::GetNumBreakpointLocationsFromEvent(vEvent);
291 return MIstatus::success;
293 lldb::SBBreakpoint brkPt = lldb::SBBreakpoint::GetBreakpointFromEvent(vEvent);
294 const CMIUtilString plural((nLoc == 1) ? "" : "s");
295 const CMIUtilString msg(
296 CMIUtilString::Format("%d location%s added to breakpoint %d", nLoc,
297 plural.c_str(), brkPt.GetID()));
299 return TextToStdout(msg);
303 //------------------------------------------------------------------------------------
304 // Details: Handle a LLDB SBBreakpoint event.
306 // Args: vEvent - (R) An LLDB broadcast event.
307 // Return: MIstatus::success - Functionality succeeded.
308 // MIstatus::failure - Functionality failed.
311 bool CMICmnLLDBDebuggerHandleEvents::HandleEventSBBreakpointCmn(
312 const lldb::SBEvent &vEvent) {
313 lldb::SBBreakpoint brkPt = lldb::SBBreakpoint::GetBreakpointFromEvent(vEvent);
314 if (!brkPt.IsValid())
315 return MIstatus::success;
317 CMICmnLLDBDebugSessionInfo &rSessionInfo(
318 CMICmnLLDBDebugSessionInfo::Instance());
319 CMICmnLLDBDebugSessionInfo::SBrkPtInfo sBrkPtInfo;
320 if (!rSessionInfo.GetBrkPtInfo(brkPt, sBrkPtInfo)) {
322 CMIUtilString::Format(MIRSRC(IDS_LLDBOUTOFBAND_ERR_BRKPT_INFO_GET),
323 "HandleEventSBBreakpointCmn()", brkPt.GetID()));
324 return MIstatus::failure;
327 // CODETAG_LLDB_BREAKPOINT_CREATION
328 // This is in a worker thread
329 // Add more breakpoint information or overwrite existing information
330 CMICmnLLDBDebugSessionInfo::SBrkPtInfo sBrkPtInfoRec;
331 if (!rSessionInfo.RecordBrkPtInfoGet(brkPt.GetID(), sBrkPtInfoRec)) {
333 CMIUtilString::Format(MIRSRC(IDS_LLDBOUTOFBAND_ERR_BRKPT_NOTFOUND),
334 "HandleEventSBBreakpointCmn()", brkPt.GetID()));
335 return MIstatus::failure;
337 sBrkPtInfo.m_bDisp = sBrkPtInfoRec.m_bDisp;
338 sBrkPtInfo.m_bEnabled = brkPt.IsEnabled();
339 sBrkPtInfo.m_bHaveArgOptionThreadGrp = false;
340 sBrkPtInfo.m_strOptThrdGrp = "";
341 sBrkPtInfo.m_nTimes = brkPt.GetHitCount();
342 sBrkPtInfo.m_strOrigLoc = sBrkPtInfoRec.m_strOrigLoc;
343 sBrkPtInfo.m_nIgnore = sBrkPtInfoRec.m_nIgnore;
344 sBrkPtInfo.m_bPending = sBrkPtInfoRec.m_bPending;
345 sBrkPtInfo.m_bCondition = sBrkPtInfoRec.m_bCondition;
346 sBrkPtInfo.m_strCondition = sBrkPtInfoRec.m_strCondition;
347 sBrkPtInfo.m_bBrkPtThreadId = sBrkPtInfoRec.m_bBrkPtThreadId;
348 sBrkPtInfo.m_nBrkPtThreadId = sBrkPtInfoRec.m_nBrkPtThreadId;
351 // "=breakpoint-modified,bkpt={number=\"%d\",type=\"breakpoint\",disp=\"%s\",enabled=\"%c\",addr=\"0x%016"
353 // func=\"%s\",file=\"%s\",fullname=\"%s/%s\",line=\"%d\",times=\"%d\",original-location=\"%s\"}"
354 CMICmnMIValueTuple miValueTuple;
355 if (!rSessionInfo.MIResponseFormBrkPtInfo(sBrkPtInfo, miValueTuple)) {
357 CMIUtilString::Format(MIRSRC(IDS_LLDBOUTOFBAND_ERR_FORM_MI_RESPONSE),
358 "HandleEventSBBreakpointCmn()"));
359 return MIstatus::failure;
362 const CMICmnMIValueResult miValueResultC("bkpt", miValueTuple);
363 const CMICmnMIOutOfBandRecord miOutOfBandRecord(
364 CMICmnMIOutOfBandRecord::eOutOfBand_BreakPointModified, miValueResultC);
365 bool bOk = MiOutOfBandRecordToStdout(miOutOfBandRecord);
366 bOk = bOk && CMICmnStreamStdout::WritePrompt();
372 //------------------------------------------------------------------------------------
373 // Details: Handle a LLDB SBBreakpoint added event.
374 // Add more breakpoint information or overwrite existing information.
375 // Normally a break point session info objects exists by now when an MI
377 // was issued to insert a break so the retrieval would normally always
379 // however should a user type "b main" into a console then LLDB will
381 // breakpoint directly, hence no MI command, hence no previous record
383 // breakpoint so RecordBrkPtInfoGet() will fail. We still get the event
385 // so need to create a breakpoint info object here and send appropriate
389 // Args: vEvent - (R) An LLDB broadcast event.
390 // Return: MIstatus::success - Functionality succeeded.
391 // MIstatus::failure - Functionality failed.
394 bool CMICmnLLDBDebuggerHandleEvents::HandleEventSBBreakpointAdded(
395 const lldb::SBEvent &vEvent) {
396 lldb::SBBreakpoint brkPt = lldb::SBBreakpoint::GetBreakpointFromEvent(vEvent);
397 if (!brkPt.IsValid())
398 return MIstatus::success;
400 CMICmnLLDBDebugSessionInfo &rSessionInfo(
401 CMICmnLLDBDebugSessionInfo::Instance());
402 CMICmnLLDBDebugSessionInfo::SBrkPtInfo sBrkPtInfo;
403 if (!rSessionInfo.GetBrkPtInfo(brkPt, sBrkPtInfo)) {
405 CMIUtilString::Format(MIRSRC(IDS_LLDBOUTOFBAND_ERR_BRKPT_INFO_GET),
406 "HandleEventSBBreakpointAdded()", brkPt.GetID()));
407 return MIstatus::failure;
410 // CODETAG_LLDB_BREAKPOINT_CREATION
411 // This is in a worker thread
412 CMICmnLLDBDebugSessionInfo::SBrkPtInfo sBrkPtInfoRec;
413 const bool bBrkPtExistAlready =
414 rSessionInfo.RecordBrkPtInfoGet(brkPt.GetID(), sBrkPtInfoRec);
415 if (bBrkPtExistAlready) {
416 // Update breakpoint information object
417 sBrkPtInfo.m_bDisp = sBrkPtInfoRec.m_bDisp;
418 sBrkPtInfo.m_bEnabled = brkPt.IsEnabled();
419 sBrkPtInfo.m_bHaveArgOptionThreadGrp = false;
420 sBrkPtInfo.m_strOptThrdGrp.clear();
421 sBrkPtInfo.m_nTimes = brkPt.GetHitCount();
422 sBrkPtInfo.m_strOrigLoc = sBrkPtInfoRec.m_strOrigLoc;
423 sBrkPtInfo.m_nIgnore = sBrkPtInfoRec.m_nIgnore;
424 sBrkPtInfo.m_bPending = sBrkPtInfoRec.m_bPending;
425 sBrkPtInfo.m_bCondition = sBrkPtInfoRec.m_bCondition;
426 sBrkPtInfo.m_strCondition = sBrkPtInfoRec.m_strCondition;
427 sBrkPtInfo.m_bBrkPtThreadId = sBrkPtInfoRec.m_bBrkPtThreadId;
428 sBrkPtInfo.m_nBrkPtThreadId = sBrkPtInfoRec.m_nBrkPtThreadId;
430 // Create a breakpoint information object
431 sBrkPtInfo.m_bDisp = brkPt.IsOneShot();
432 sBrkPtInfo.m_bEnabled = brkPt.IsEnabled();
433 sBrkPtInfo.m_bHaveArgOptionThreadGrp = false;
434 sBrkPtInfo.m_strOptThrdGrp.clear();
435 sBrkPtInfo.m_strOrigLoc = CMIUtilString::Format(
436 "%s:%d", sBrkPtInfo.m_fileName.c_str(), sBrkPtInfo.m_nLine);
437 sBrkPtInfo.m_nIgnore = brkPt.GetIgnoreCount();
438 sBrkPtInfo.m_bPending = false;
439 const char *pStrCondition = brkPt.GetCondition();
440 sBrkPtInfo.m_bCondition = pStrCondition != nullptr;
441 sBrkPtInfo.m_strCondition =
442 (pStrCondition != nullptr) ? pStrCondition : "??";
443 sBrkPtInfo.m_bBrkPtThreadId = brkPt.GetThreadID() != 0;
444 sBrkPtInfo.m_nBrkPtThreadId = brkPt.GetThreadID();
447 CMICmnMIValueTuple miValueTuple;
448 if (!rSessionInfo.MIResponseFormBrkPtInfo(sBrkPtInfo, miValueTuple)) {
450 CMIUtilString::Format(MIRSRC(IDS_LLDBOUTOFBAND_ERR_FORM_MI_RESPONSE),
451 "HandleEventSBBreakpointAdded()"));
452 return MIstatus::failure;
455 bool bOk = MIstatus::success;
456 if (bBrkPtExistAlready) {
458 // "=breakpoint-modified,bkpt={number=\"%d\",type=\"breakpoint\",disp=\"%s\",enabled=\"%c\",addr=\"0x%016"
460 // "\",func=\"%s\",file=\"%s\",fullname=\"%s/%s\",line=\"%d\",times=\"%d\",original-location=\"%s\"}"
461 const CMICmnMIValueResult miValueResult("bkpt", miValueTuple);
462 const CMICmnMIOutOfBandRecord miOutOfBandRecord(
463 CMICmnMIOutOfBandRecord::eOutOfBand_BreakPointModified, miValueResult);
464 bOk = MiOutOfBandRecordToStdout(miOutOfBandRecord);
465 bOk = bOk && CMICmnStreamStdout::WritePrompt();
467 // CODETAG_LLDB_BRKPT_ID_MAX
468 if (brkPt.GetID() > (lldb::break_id_t)rSessionInfo.m_nBrkPointCntMax) {
469 SetErrorDescription(CMIUtilString::Format(
470 MIRSRC(IDS_CMD_ERR_BRKPT_CNT_EXCEEDED),
471 "HandleEventSBBreakpointAdded()", rSessionInfo.m_nBrkPointCntMax,
473 return MIstatus::failure;
475 if (!rSessionInfo.RecordBrkPtInfo(brkPt.GetID(), sBrkPtInfo)) {
476 SetErrorDescription(CMIUtilString::Format(
477 MIRSRC(IDS_LLDBOUTOFBAND_ERR_BRKPT_INFO_SET),
478 "HandleEventSBBreakpointAdded()", sBrkPtInfo.m_id));
479 return MIstatus::failure;
483 // "=breakpoint-created,bkpt={number=\"%d\",type=\"breakpoint\",disp=\"%s\",enabled=\"%c\",addr=\"0x%016"
485 // "\",func=\"%s\",file=\"%s\",fullname=\"%s/%s\",line=\"%d\",times=\"%d\",original-location=\"%s\"}"
486 const CMICmnMIValueResult miValueResult("bkpt", miValueTuple);
487 const CMICmnMIOutOfBandRecord miOutOfBandRecord(
488 CMICmnMIOutOfBandRecord::eOutOfBand_BreakPointCreated, miValueResult);
489 bOk = MiOutOfBandRecordToStdout(miOutOfBandRecord);
490 bOk = bOk && CMICmnStreamStdout::WritePrompt();
497 //------------------------------------------------------------------------------------
498 // Details: Handle a LLDB SBThread event.
500 // Args: vEvent - (R) An LLDB broadcast event.
501 // Return: MIstatus::success - Functionality succeeded.
502 // MIstatus::failure - Functionality failed.
505 bool CMICmnLLDBDebuggerHandleEvents::HandleEventSBThread(
506 const lldb::SBEvent &vEvent) {
507 if (!ChkForStateChanges())
508 return MIstatus::failure;
510 bool bOk = MIstatus::success;
511 const char *pEventType = "";
512 const MIuint nEventType = vEvent.GetType();
513 switch (nEventType) {
514 case lldb::SBThread::eBroadcastBitStackChanged:
515 pEventType = "eBroadcastBitStackChanged";
516 bOk = HandleEventSBThreadBitStackChanged(vEvent);
518 case lldb::SBThread::eBroadcastBitThreadSuspended:
519 pEventType = "eBroadcastBitThreadSuspended";
520 bOk = HandleEventSBThreadSuspended(vEvent);
522 case lldb::SBThread::eBroadcastBitThreadResumed:
523 pEventType = "eBroadcastBitThreadResumed";
525 case lldb::SBThread::eBroadcastBitSelectedFrameChanged:
526 pEventType = "eBroadcastBitSelectedFrameChanged";
528 case lldb::SBThread::eBroadcastBitThreadSelected:
529 pEventType = "eBroadcastBitThreadSelected";
532 const CMIUtilString msg(
533 CMIUtilString::Format(MIRSRC(IDS_LLDBOUTOFBAND_ERR_UNKNOWN_EVENT),
534 "SBThread", (MIuint)nEventType));
535 SetErrorDescription(msg);
536 return MIstatus::failure;
539 m_pLog->WriteLog(CMIUtilString::Format("##### An SBThread event occurred: %s",
546 //------------------------------------------------------------------------------------
547 // Details: Handle a LLDB SBThread event.
549 // Args: vEvent - (R) An LLDB broadcast event.
550 // Return: MIstatus::success - Functionality succeeded.
551 // MIstatus::failure - Functionality failed.
554 bool CMICmnLLDBDebuggerHandleEvents::HandleEventSBThreadSuspended(
555 const lldb::SBEvent &vEvent) {
556 lldb::SBThread thread = lldb::SBThread::GetThreadFromEvent(vEvent);
557 if (!thread.IsValid())
558 return MIstatus::success;
560 const lldb::StopReason eStopReason = thread.GetStopReason();
561 if (eStopReason != lldb::eStopReasonSignal)
562 return MIstatus::success;
564 // MI print "@thread=%d,signal=%lld"
565 const MIuint64 nId = thread.GetStopReasonDataAtIndex(0);
566 const CMIUtilString strThread(
567 CMIUtilString::Format("%d", thread.GetThreadID()));
568 const CMICmnMIValueConst miValueConst(strThread);
569 const CMICmnMIValueResult miValueResult("thread", miValueConst);
570 CMICmnMIOutOfBandRecord miOutOfBandRecord(
571 CMICmnMIOutOfBandRecord::eOutOfBand_Thread, miValueResult);
572 const CMIUtilString strSignal(CMIUtilString::Format("%lld", nId));
573 const CMICmnMIValueConst miValueConst2(strSignal);
574 const CMICmnMIValueResult miValueResult2("signal", miValueConst2);
575 miOutOfBandRecord.Add(miValueResult2);
576 return MiOutOfBandRecordToStdout(miOutOfBandRecord);
580 //------------------------------------------------------------------------------------
581 // Details: Handle a LLDB SBThread event.
583 // Args: vEvent - (R) An LLDB broadcast event.
584 // Return: MIstatus::success - Functionality succeeded.
585 // MIstatus::failure - Functionality failed.
588 bool CMICmnLLDBDebuggerHandleEvents::HandleEventSBThreadBitStackChanged(
589 const lldb::SBEvent &vEvent) {
590 lldb::SBThread thread = lldb::SBThread::GetThreadFromEvent(vEvent);
591 if (!thread.IsValid())
592 return MIstatus::success;
594 lldb::SBStream streamOut;
595 const bool bOk = thread.GetStatus(streamOut);
596 return bOk && TextToStdout(streamOut.GetData());
600 //------------------------------------------------------------------------------------
601 // Details: Handle a LLDB SBTarget event.
603 // Args: vEvent - (R) An LLDB broadcast event.
604 // Return: MIstatus::success - Functional succeeded.
605 // MIstatus::failure - Functional failed.
608 bool CMICmnLLDBDebuggerHandleEvents::HandleEventSBTarget(
609 const lldb::SBEvent &vEvent) {
610 if (!ChkForStateChanges())
611 return MIstatus::failure;
613 bool bOk = MIstatus::success;
614 const char *pEventType = "";
615 const MIuint nEventType = vEvent.GetType();
616 switch (nEventType) {
617 case lldb::SBTarget::eBroadcastBitBreakpointChanged:
618 pEventType = "eBroadcastBitBreakpointChanged";
620 case lldb::SBTarget::eBroadcastBitModulesLoaded:
621 pEventType = "eBroadcastBitModulesLoaded";
622 bOk = HandleTargetEventBroadcastBitModulesLoaded(vEvent);
624 case lldb::SBTarget::eBroadcastBitModulesUnloaded:
625 pEventType = "eBroadcastBitModulesUnloaded";
626 bOk = HandleTargetEventBroadcastBitModulesUnloaded(vEvent);
628 case lldb::SBTarget::eBroadcastBitWatchpointChanged:
629 pEventType = "eBroadcastBitWatchpointChanged";
631 case lldb::SBTarget::eBroadcastBitSymbolsLoaded:
632 pEventType = "eBroadcastBitSymbolsLoaded";
635 const CMIUtilString msg(
636 CMIUtilString::Format(MIRSRC(IDS_LLDBOUTOFBAND_ERR_UNKNOWN_EVENT),
637 "SBTarget", (MIuint)nEventType));
638 SetErrorDescription(msg);
639 return MIstatus::failure;
642 m_pLog->WriteLog(CMIUtilString::Format("##### An SBTarget event occurred: %s",
649 //------------------------------------------------------------------------------------
650 // Details: Print to stdout
651 // "=library-loaded,id=\"%s\",target-name=\"%s\",host-name=\"%s\",symbols-loaded="%d"[,symbols-path=\"%s\"],loaded_addr=\"0x%016"
655 // Return: MIstatus::success - Function succeeded.
656 // MIstatus::failure - Function failed.
659 bool CMICmnLLDBDebuggerHandleEvents::HandleTargetEventBroadcastBitModulesLoaded(
660 const lldb::SBEvent &vEvent) {
661 bool bOk = MIstatus::failure;
662 const MIuint nSize = lldb::SBTarget::GetNumModulesFromEvent(vEvent);
663 for (MIuint nIndex = 0; nIndex < nSize; ++nIndex) {
664 const lldb::SBModule sbModule =
665 lldb::SBTarget::GetModuleAtIndexFromEvent(nIndex, vEvent);
666 CMICmnMIOutOfBandRecord miOutOfBandRecord(
667 CMICmnMIOutOfBandRecord::eOutOfBand_TargetModuleLoaded);
668 const bool bWithExtraFields = true;
669 bOk = MiHelpGetModuleInfo(sbModule, bWithExtraFields, miOutOfBandRecord);
670 bOk = bOk && MiOutOfBandRecordToStdout(miOutOfBandRecord);
679 //------------------------------------------------------------------------------------
680 // Details: Print to stdout
681 // "=library-unloaded,id=\"%s\",target-name=\"%s\",host-name=\"%s\",symbols-loaded="%d"[,symbols-path=\"%s\"],loaded_addr=\"0x%016"
685 // Return: MIstatus::success - Function succeeded.
686 // MIstatus::failure - Function failed.
689 bool CMICmnLLDBDebuggerHandleEvents::
690 HandleTargetEventBroadcastBitModulesUnloaded(const lldb::SBEvent &vEvent) {
691 bool bOk = MIstatus::failure;
692 const MIuint nSize = lldb::SBTarget::GetNumModulesFromEvent(vEvent);
693 for (MIuint nIndex = 0; nIndex < nSize; ++nIndex) {
694 const lldb::SBModule sbModule =
695 lldb::SBTarget::GetModuleAtIndexFromEvent(nIndex, vEvent);
696 CMICmnMIOutOfBandRecord miOutOfBandRecord(
697 CMICmnMIOutOfBandRecord::eOutOfBand_TargetModuleUnloaded);
698 const bool bWithExtraFields = false;
699 bOk = MiHelpGetModuleInfo(sbModule, bWithExtraFields, miOutOfBandRecord);
700 bOk = bOk && MiOutOfBandRecordToStdout(miOutOfBandRecord);
709 //------------------------------------------------------------------------------------
710 // Details: Build module information for =library-loaded/=library-unloaded:
711 // "id=\"%s\",target-name=\"%s\",host-name=\"%s\",symbols-loaded="%d"[,symbols-path=\"%s\"],loaded_addr=\"0x%016"
714 // Args: vwrMiValueList - (W) MI value list object.
715 // Return: MIstatus::success - Function succeeded.
716 // MIstatus::failure - Function failed.
719 bool CMICmnLLDBDebuggerHandleEvents::MiHelpGetModuleInfo(
720 const lldb::SBModule &vModule, const bool vbWithExtraFields,
721 CMICmnMIOutOfBandRecord &vwrMiOutOfBandRecord) {
722 bool bOk = MIstatus::success;
724 // First, build standard fields:
726 std::unique_ptr<char[]> apPath(new char[PATH_MAX]);
727 vModule.GetFileSpec().GetPath(apPath.get(), PATH_MAX);
728 const CMIUtilString strTargetPath(apPath.get());
729 const CMICmnMIValueConst miValueConst(strTargetPath.AddSlashes());
730 const CMICmnMIValueResult miValueResult("id", miValueConst);
731 vwrMiOutOfBandRecord.Add(miValueResult);
732 // Build "target-name" field
733 const CMICmnMIValueConst miValueConst2(strTargetPath.AddSlashes());
734 const CMICmnMIValueResult miValueResult2("target-name", miValueConst2);
735 vwrMiOutOfBandRecord.Add(miValueResult2);
736 // Build "host-name" field
737 vModule.GetPlatformFileSpec().GetPath(apPath.get(), PATH_MAX);
738 const CMIUtilString strHostPath(apPath.get());
739 const CMICmnMIValueConst miValueConst3(strHostPath.AddSlashes());
740 const CMICmnMIValueResult miValueResult3("host-name", miValueConst3);
741 vwrMiOutOfBandRecord.Add(miValueResult3);
743 // Then build extra fields if needed:
744 if (vbWithExtraFields) {
745 // Build "symbols-loaded" field
746 vModule.GetSymbolFileSpec().GetPath(apPath.get(), PATH_MAX);
747 const CMIUtilString strSymbolsPath(apPath.get());
748 const bool bSymbolsLoaded =
749 !CMIUtilString::Compare(strHostPath, strSymbolsPath);
750 const CMICmnMIValueConst miValueConst4(
751 CMIUtilString::Format("%d", bSymbolsLoaded));
752 const CMICmnMIValueResult miValueResult4("symbols-loaded", miValueConst4);
753 vwrMiOutOfBandRecord.Add(miValueResult4);
754 // Build "symbols-path" field
755 if (bSymbolsLoaded) {
756 const CMICmnMIValueConst miValueConst5(strSymbolsPath.AddSlashes());
757 const CMICmnMIValueResult miValueResult5("symbols-path", miValueConst5);
758 vwrMiOutOfBandRecord.Add(miValueResult5);
760 // Build "loaded_addr" field
761 lldb::SBAddress sbAddress(vModule.GetObjectFileHeaderAddress());
762 CMICmnLLDBDebugSessionInfo &rSessionInfo(
763 CMICmnLLDBDebugSessionInfo::Instance());
764 const lldb::addr_t nLoadAddress(
765 sbAddress.GetLoadAddress(rSessionInfo.GetTarget()));
766 const CMIUtilString strLoadedAddr(
767 nLoadAddress != LLDB_INVALID_ADDRESS
768 ? CMIUtilString::Format("0x%016" PRIx64, nLoadAddress)
770 const CMICmnMIValueConst miValueConst6(strLoadedAddr);
771 const CMICmnMIValueResult miValueResult6("loaded_addr", miValueConst6);
772 vwrMiOutOfBandRecord.Add(miValueResult6);
774 // Build "size" field
775 lldb::SBSection sbSection = sbAddress.GetSection();
776 const CMIUtilString strSize(
777 CMIUtilString::Format("%" PRIu64, sbSection.GetByteSize()));
778 const CMICmnMIValueConst miValueConst7(strSize);
779 const CMICmnMIValueResult miValueResult7("size", miValueConst7);
780 vwrMiOutOfBandRecord.Add(miValueResult7);
787 //------------------------------------------------------------------------------------
788 // Details: Handle a LLDB SBCommandInterpreter event.
790 // Args: vEvent - (R) An LLDB command interpreter event.
791 // Return: MIstatus::success - Functionality succeeded.
792 // MIstatus::failure - Functionality failed.
795 bool CMICmnLLDBDebuggerHandleEvents::HandleEventSBCommandInterpreter(
796 const lldb::SBEvent &vEvent) {
797 // This function is not used
798 // *** This function is under development
800 const char *pEventType = "";
801 const MIuint nEventType = vEvent.GetType();
802 switch (nEventType) {
803 case lldb::SBCommandInterpreter::eBroadcastBitThreadShouldExit:
804 pEventType = "eBroadcastBitThreadShouldExit";
805 // ToDo: IOR: Reminder to maybe handle this here
806 // const MIuint nEventType = event.GetType();
808 // lldb::SBCommandInterpreter::eBroadcastBitThreadShouldExit)
810 // m_pClientDriver->SetExitApplicationFlag();
811 // vrbYesExit = true;
812 // return MIstatus::success;
815 case lldb::SBCommandInterpreter::eBroadcastBitResetPrompt:
816 pEventType = "eBroadcastBitResetPrompt";
818 case lldb::SBCommandInterpreter::eBroadcastBitQuitCommandReceived: {
819 pEventType = "eBroadcastBitQuitCommandReceived";
820 const bool bForceExit = true;
821 CMICmnLLDBDebugger::Instance().GetDriver().SetExitApplicationFlag(
825 case lldb::SBCommandInterpreter::eBroadcastBitAsynchronousOutputData:
826 pEventType = "eBroadcastBitAsynchronousOutputData";
828 case lldb::SBCommandInterpreter::eBroadcastBitAsynchronousErrorData:
829 pEventType = "eBroadcastBitAsynchronousErrorData";
832 const CMIUtilString msg(
833 CMIUtilString::Format(MIRSRC(IDS_LLDBOUTOFBAND_ERR_UNKNOWN_EVENT),
834 "SBCommandInterpreter", (MIuint)nEventType));
835 SetErrorDescription(msg);
836 return MIstatus::failure;
839 m_pLog->WriteLog(CMIUtilString::Format(
840 "##### An SBCommandInterpreter event occurred: %s", pEventType));
842 return MIstatus::success;
846 //------------------------------------------------------------------------------------
847 // Details: Handle SBProcess event eBroadcastBitStateChanged.
849 // Args: vEvent - (R) An LLDB event object.
850 // Return: MIstatus::success - Functionality succeeded.
851 // MIstatus::failure - Functionality failed.
854 bool CMICmnLLDBDebuggerHandleEvents::HandleProcessEventBroadcastBitStateChanged(
855 const lldb::SBEvent &vEvent) {
856 // Make sure the program hasn't been auto-restarted:
857 if (lldb::SBProcess::GetRestartedFromEvent(vEvent))
858 return MIstatus::success;
860 bool bOk = ChkForStateChanges();
861 bOk = bOk && GetProcessStdout();
862 bOk = bOk && GetProcessStderr();
864 return MIstatus::failure;
866 // Something changed in the process; get the event and report the process's
868 // status and location
869 const lldb::StateType eEventState =
870 lldb::SBProcess::GetStateFromEvent(vEvent);
871 if (eEventState == lldb::eStateInvalid)
872 return MIstatus::success;
874 lldb::SBProcess process = lldb::SBProcess::GetProcessFromEvent(vEvent);
875 if (!process.IsValid()) {
876 const CMIUtilString msg(CMIUtilString::Format(
877 MIRSRC(IDS_LLDBOUTOFBAND_ERR_PROCESS_INVALID), "SBProcess",
878 "HandleProcessEventBroadcastBitStateChanged()"));
879 SetErrorDescription(msg);
880 return MIstatus::failure;
883 bool bShouldBrk = true;
884 const char *pEventType = "";
885 switch (eEventState) {
886 case lldb::eStateUnloaded:
887 pEventType = "eStateUnloaded";
889 case lldb::eStateConnected:
890 pEventType = "eStateConnected";
892 case lldb::eStateAttaching:
893 pEventType = "eStateAttaching";
895 case lldb::eStateLaunching:
896 pEventType = "eStateLaunching";
898 case lldb::eStateStopped:
899 pEventType = "eStateStopped";
900 bOk = HandleProcessEventStateStopped(vEvent, bShouldBrk);
904 case lldb::eStateCrashed:
905 case lldb::eStateSuspended:
906 pEventType = "eStateSuspended";
907 bOk = HandleProcessEventStateSuspended(vEvent);
909 case lldb::eStateRunning:
910 pEventType = "eStateRunning";
911 bOk = HandleProcessEventStateRunning();
913 case lldb::eStateStepping:
914 pEventType = "eStateStepping";
916 case lldb::eStateDetached:
917 pEventType = "eStateDetached";
919 case lldb::eStateExited:
920 // Don't exit from lldb-mi here. We should be able to re-run target.
921 pEventType = "eStateExited";
922 bOk = HandleProcessEventStateExited();
925 const CMIUtilString msg(CMIUtilString::Format(
926 MIRSRC(IDS_LLDBOUTOFBAND_ERR_UNKNOWN_EVENT),
927 "SBProcess BroadcastBitStateChanged", (MIuint)eEventState));
928 SetErrorDescription(msg);
929 return MIstatus::failure;
933 // ToDo: Remove when finished coding application
934 m_pLog->WriteLog(CMIUtilString::Format(
935 "##### An SB Process event BroadcastBitStateChanged occurred: %s",
942 //------------------------------------------------------------------------------------
943 // Details: Asynchronous event handler for LLDB Process state suspended.
945 // Args: vEvent - (R) An LLDB event object.
946 // Return: MIstatus::success - Functionality succeeded.
947 // MIstatus::failure - Functionality failed.
950 bool CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStateSuspended(
951 const lldb::SBEvent &vEvent) {
952 bool bOk = MIstatus::success;
953 lldb::SBStream streamOut;
954 lldb::SBDebugger &rDebugger =
955 CMICmnLLDBDebugSessionInfo::Instance().GetDebugger();
956 lldb::SBProcess sbProcess =
957 CMICmnLLDBDebugSessionInfo::Instance().GetProcess();
958 lldb::SBTarget target = sbProcess.GetTarget();
959 if (rDebugger.GetSelectedTarget() == target) {
960 if (!UpdateSelectedThread())
961 return MIstatus::failure;
962 sbProcess.GetDescription(streamOut);
963 // Add a delimiter between process' and threads' info.
964 streamOut.Printf("\n");
965 for (uint32_t i = 0, e = sbProcess.GetNumThreads(); i < e; ++i) {
966 const lldb::SBThread thread = sbProcess.GetThreadAtIndex(i);
967 if (!thread.IsValid())
969 thread.GetDescription(streamOut);
971 bOk = TextToStdout(streamOut.GetData());
973 const MIuint nTargetIndex = rDebugger.GetIndexOfTarget(target);
974 if (nTargetIndex != UINT_MAX)
975 streamOut.Printf("Target %d: (", nTargetIndex);
977 streamOut.Printf("Target <unknown index>: (");
978 target.GetDescription(streamOut, lldb::eDescriptionLevelBrief);
979 streamOut.Printf(") stopped.\n");
980 bOk = TextToStdout(streamOut.GetData());
987 //------------------------------------------------------------------------------------
988 // Details: Print to stdout MI formatted text to indicate process stopped.
990 // Args: vwrbShouldBrk - (W) True = Yes break, false = do not.
991 // Return: MIstatus::success - Functionality succeeded.
992 // MIstatus::failure - Functionality failed.
995 bool CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStateStopped(
996 const lldb::SBEvent &vrEvent, bool &vwrbShouldBrk) {
997 if (!UpdateSelectedThread())
998 return MIstatus::failure;
1000 const char *pEventType = "";
1001 bool bOk = MIstatus::success;
1002 lldb::SBProcess sbProcess =
1003 CMICmnLLDBDebugSessionInfo::Instance().GetProcess();
1004 const lldb::StopReason eStoppedReason =
1005 sbProcess.GetSelectedThread().GetStopReason();
1006 switch (eStoppedReason) {
1007 case lldb::eStopReasonInvalid:
1008 pEventType = "eStopReasonInvalid";
1009 vwrbShouldBrk = false;
1011 case lldb::eStopReasonNone:
1012 pEventType = "eStopReasonNone";
1014 case lldb::eStopReasonTrace:
1015 pEventType = "eStopReasonTrace";
1016 bOk = HandleProcessEventStopReasonTrace();
1018 case lldb::eStopReasonBreakpoint:
1019 pEventType = "eStopReasonBreakpoint";
1020 bOk = HandleProcessEventStopReasonBreakpoint();
1022 case lldb::eStopReasonWatchpoint:
1023 pEventType = "eStopReasonWatchpoint";
1025 case lldb::eStopReasonSignal:
1026 pEventType = "eStopReasonSignal";
1027 bOk = HandleProcessEventStopSignal(vrEvent);
1029 case lldb::eStopReasonException:
1030 pEventType = "eStopReasonException";
1031 bOk = HandleProcessEventStopException();
1033 case lldb::eStopReasonExec:
1034 pEventType = "eStopReasonExec";
1036 case lldb::eStopReasonPlanComplete:
1037 pEventType = "eStopReasonPlanComplete";
1038 bOk = HandleProcessEventStopReasonTrace();
1040 case lldb::eStopReasonThreadExiting:
1041 pEventType = "eStopReasonThreadExiting";
1043 case lldb::eStopReasonInstrumentation:
1044 pEventType = "eStopReasonInstrumentation";
1048 // ToDo: Remove when finished coding application
1049 m_pLog->WriteLog(CMIUtilString::Format(
1050 "##### An SB Process event stop state occurred: %s", pEventType));
1056 //------------------------------------------------------------------------------------
1057 // Details: Asynchronous event handler for LLDB Process stop signal.
1059 // Args: vrEvent - (R) An LLDB broadcast event.
1060 // Return: MIstatus::success - Functionality succeeded.
1061 // MIstatus::failure - Functionality failed.
1064 bool CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStopSignal(
1065 const lldb::SBEvent &vrEvent) {
1066 bool bOk = MIstatus::success;
1068 InitializeSignals();
1069 lldb::SBProcess sbProcess =
1070 CMICmnLLDBDebugSessionInfo::Instance().GetProcess();
1071 const MIuint64 nStopReason =
1072 sbProcess.GetSelectedThread().GetStopReasonDataAtIndex(0);
1073 const bool bInterrupted = lldb::SBProcess::GetInterruptedFromEvent(vrEvent);
1074 if (nStopReason == m_SIGINT || (nStopReason == m_SIGSTOP && bInterrupted)) {
1076 // "*stopped,reason=\"signal-received\",signal-name=\"SIGINT\",signal-meaning=\"Interrupt\",frame={%s},thread-id=\"%d\",stopped-threads=\"all\""
1077 const CMICmnMIValueConst miValueConst("signal-received");
1078 const CMICmnMIValueResult miValueResult("reason", miValueConst);
1079 CMICmnMIOutOfBandRecord miOutOfBandRecord(
1080 CMICmnMIOutOfBandRecord::eOutOfBand_Stopped, miValueResult);
1081 const CMICmnMIValueConst miValueConst2("SIGINT");
1082 const CMICmnMIValueResult miValueResult2("signal-name", miValueConst2);
1083 miOutOfBandRecord.Add(miValueResult2);
1084 const CMICmnMIValueConst miValueConst3("Interrupt");
1085 const CMICmnMIValueResult miValueResult3("signal-meaning", miValueConst3);
1086 miOutOfBandRecord.Add(miValueResult3);
1087 CMICmnMIValueTuple miValueTuple;
1088 bOk = bOk && MiHelpGetCurrentThreadFrame(miValueTuple);
1089 const CMICmnMIValueResult miValueResult4("frame", miValueTuple);
1090 miOutOfBandRecord.Add(miValueResult4);
1091 const CMIUtilString strThreadId(CMIUtilString::Format(
1092 "%" PRIu32, sbProcess.GetSelectedThread().GetIndexID()));
1093 const CMICmnMIValueConst miValueConst5(strThreadId);
1094 const CMICmnMIValueResult miValueResult5("thread-id", miValueConst5);
1095 miOutOfBandRecord.Add(miValueResult5);
1096 const CMICmnMIValueConst miValueConst6("all");
1097 const CMICmnMIValueResult miValueResult6("stopped-threads", miValueConst6);
1098 miOutOfBandRecord.Add(miValueResult6);
1099 bOk = bOk && MiOutOfBandRecordToStdout(miOutOfBandRecord);
1100 bOk = bOk && CMICmnStreamStdout::WritePrompt();
1101 } else if (nStopReason == m_SIGSTOP) {
1103 // "*stopped,reason=\"signal-received\",signal-name=\"SIGSTOP\",signal-meaning=\"Stop\",frame={%s},thread-id=\"%d\",stopped-threads=\"all\""
1104 const CMICmnMIValueConst miValueConst("signal-received");
1105 const CMICmnMIValueResult miValueResult("reason", miValueConst);
1106 CMICmnMIOutOfBandRecord miOutOfBandRecord(
1107 CMICmnMIOutOfBandRecord::eOutOfBand_Stopped, miValueResult);
1108 const CMICmnMIValueConst miValueConst2("SIGSTOP");
1109 const CMICmnMIValueResult miValueResult2("signal-name", miValueConst2);
1110 miOutOfBandRecord.Add(miValueResult2);
1111 const CMICmnMIValueConst miValueConst3("Stop");
1112 const CMICmnMIValueResult miValueResult3("signal-meaning", miValueConst3);
1113 miOutOfBandRecord.Add(miValueResult3);
1114 CMICmnMIValueTuple miValueTuple;
1115 bOk = bOk && MiHelpGetCurrentThreadFrame(miValueTuple);
1116 const CMICmnMIValueResult miValueResult4("frame", miValueTuple);
1117 miOutOfBandRecord.Add(miValueResult4);
1118 const CMIUtilString strThreadId(CMIUtilString::Format(
1119 "%" PRIu32, sbProcess.GetSelectedThread().GetIndexID()));
1120 const CMICmnMIValueConst miValueConst5(strThreadId);
1121 const CMICmnMIValueResult miValueResult5("thread-id", miValueConst5);
1122 miOutOfBandRecord.Add(miValueResult5);
1123 const CMICmnMIValueConst miValueConst6("all");
1124 const CMICmnMIValueResult miValueResult6("stopped-threads", miValueConst6);
1125 miOutOfBandRecord.Add(miValueResult6);
1126 bOk = bOk && MiOutOfBandRecordToStdout(miOutOfBandRecord);
1127 bOk = bOk && CMICmnStreamStdout::WritePrompt();
1128 } else if (nStopReason == m_SIGSEGV) {
1130 // "*stopped,reason=\"signal-received\",signal-name=\"SIGSEGV\",signal-meaning=\"Segmentation
1131 // fault\",thread-id=\"%d\",frame={%s}"
1132 const CMICmnMIValueConst miValueConst("signal-received");
1133 const CMICmnMIValueResult miValueResult("reason", miValueConst);
1134 CMICmnMIOutOfBandRecord miOutOfBandRecord(
1135 CMICmnMIOutOfBandRecord::eOutOfBand_Stopped, miValueResult);
1136 const CMICmnMIValueConst miValueConst2("SIGSEGV");
1137 const CMICmnMIValueResult miValueResult2("signal-name", miValueConst2);
1138 miOutOfBandRecord.Add(miValueResult2);
1139 const CMICmnMIValueConst miValueConst3("Segmentation fault");
1140 const CMICmnMIValueResult miValueResult3("signal-meaning", miValueConst3);
1141 miOutOfBandRecord.Add(miValueResult3);
1142 CMICmnMIValueTuple miValueTuple;
1143 bOk = bOk && MiHelpGetCurrentThreadFrame(miValueTuple);
1144 const CMICmnMIValueResult miValueResult4("frame", miValueTuple);
1145 miOutOfBandRecord.Add(miValueResult4);
1146 const CMIUtilString strThreadId(CMIUtilString::Format(
1147 "%d", sbProcess.GetSelectedThread().GetIndexID()));
1148 const CMICmnMIValueConst miValueConst5(strThreadId);
1149 const CMICmnMIValueResult miValueResult5("thread-id", miValueConst5);
1150 miOutOfBandRecord.Add(miValueResult5);
1151 bOk = bOk && MiOutOfBandRecordToStdout(miOutOfBandRecord);
1152 // Note no "(gdb)" output here
1153 } else if (nStopReason == m_SIGTRAP) {
1154 lldb::SBThread thread = sbProcess.GetSelectedThread();
1155 const MIuint nFrames = thread.GetNumFrames();
1157 lldb::SBFrame frame = thread.GetFrameAtIndex(0);
1158 const char *pFnName = frame.GetFunctionName();
1159 if (pFnName != nullptr) {
1160 const CMIUtilString fnName = CMIUtilString(pFnName);
1161 static const CMIUtilString threadCloneFn =
1162 CMIUtilString("__pthread_clone");
1164 if (CMIUtilString::Compare(threadCloneFn, fnName)) {
1165 if (sbProcess.IsValid())
1166 sbProcess.Continue();
1172 // "*stopped,reason=\"signal-received\",signal-name=\"%s\",thread-id=\"%d\",stopped-threads=\"all\""
1174 // "*stopped,reason=\"signal-received\",signal=\"%d\",thread-id=\"%d\",stopped-threads=\"all\""
1175 const CMICmnMIValueConst miValueConst("signal-received");
1176 const CMICmnMIValueResult miValueResult("reason", miValueConst);
1177 CMICmnMIOutOfBandRecord miOutOfBandRecord(
1178 CMICmnMIOutOfBandRecord::eOutOfBand_Stopped, miValueResult);
1179 lldb::SBUnixSignals sbUnixSignals = sbProcess.GetUnixSignals();
1180 const char *pSignal = sbUnixSignals.GetSignalAsCString(nStopReason);
1182 const CMICmnMIValueConst miValueConst2(pSignal);
1183 const CMICmnMIValueResult miValueResult2("signal-name", miValueConst2);
1184 miOutOfBandRecord.Add(miValueResult2);
1186 const CMIUtilString strSignal(
1187 CMIUtilString::Format("%" PRIu64, nStopReason));
1188 const CMICmnMIValueConst miValueConst2(strSignal);
1189 const CMICmnMIValueResult miValueResult2("signal", miValueConst2);
1190 miOutOfBandRecord.Add(miValueResult2);
1192 const CMIUtilString strThreadId(CMIUtilString::Format(
1193 "%d", sbProcess.GetSelectedThread().GetIndexID()));
1194 const CMICmnMIValueConst miValueConst3(strThreadId);
1195 const CMICmnMIValueResult miValueResult3("thread-id", miValueConst3);
1196 miOutOfBandRecord.Add(miValueResult3);
1197 const CMICmnMIValueConst miValueConst4("all");
1198 const CMICmnMIValueResult miValueResult4("stopped-threads", miValueConst4);
1199 miOutOfBandRecord.Add(miValueResult4);
1200 bOk = bOk && MiOutOfBandRecordToStdout(miOutOfBandRecord);
1201 bOk = bOk && CMICmnStreamStdout::WritePrompt();
1207 //------------------------------------------------------------------------------------
1208 // Details: Asynchronous event handler for LLDB Process stop exception.
1211 // Return: MIstatus::success - Functional succeeded.
1212 // MIstatus::failure - Functional failed.
1215 bool CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStopException() {
1216 const lldb::SBProcess sbProcess =
1217 CMICmnLLDBDebugSessionInfo::Instance().GetProcess();
1218 lldb::SBThread sbThread = sbProcess.GetSelectedThread();
1219 const size_t nStopDescriptionLen = sbThread.GetStopDescription(nullptr, 0);
1220 std::unique_ptr<char[]> apStopDescription(new char[nStopDescriptionLen]);
1221 sbThread.GetStopDescription(apStopDescription.get(), nStopDescriptionLen);
1224 // "*stopped,reason=\"exception-received\",exception=\"%s\",thread-id=\"%d\",stopped-threads=\"all\""
1225 const CMICmnMIValueConst miValueConst("exception-received");
1226 const CMICmnMIValueResult miValueResult("reason", miValueConst);
1227 CMICmnMIOutOfBandRecord miOutOfBandRecord(
1228 CMICmnMIOutOfBandRecord::eOutOfBand_Stopped, miValueResult);
1229 const CMIUtilString strReason(apStopDescription.get());
1230 const CMICmnMIValueConst miValueConst2(strReason);
1231 const CMICmnMIValueResult miValueResult2("exception", miValueConst2);
1232 miOutOfBandRecord.Add(miValueResult2);
1233 const CMIUtilString strThreadId(
1234 CMIUtilString::Format("%d", sbThread.GetIndexID()));
1235 const CMICmnMIValueConst miValueConst3(strThreadId);
1236 const CMICmnMIValueResult miValueResult3("thread-id", miValueConst3);
1237 miOutOfBandRecord.Add(miValueResult3);
1238 const CMICmnMIValueConst miValueConst4("all");
1239 const CMICmnMIValueResult miValueResult4("stopped-threads", miValueConst4);
1240 miOutOfBandRecord.Add(miValueResult4);
1241 bool bOk = MiOutOfBandRecordToStdout(miOutOfBandRecord);
1242 bOk = bOk && CMICmnStreamStdout::WritePrompt();
1248 //------------------------------------------------------------------------------------
1249 // Details: Form partial MI response in a MI value tuple object.
1251 // Args: vwrMiValueTuple - (W) MI value tuple object.
1252 // Return: MIstatus::success - Functionality succeeded.
1253 // MIstatus::failure - Functionality failed.
1256 bool CMICmnLLDBDebuggerHandleEvents::MiHelpGetCurrentThreadFrame(
1257 CMICmnMIValueTuple &vwrMiValueTuple) {
1258 CMIUtilString strThreadFrame;
1259 lldb::SBProcess sbProcess =
1260 CMICmnLLDBDebugSessionInfo::Instance().GetProcess();
1261 lldb::SBThread thread = sbProcess.GetSelectedThread();
1262 const MIuint nFrame = thread.GetNumFrames();
1265 // "addr=\"??\",func=\"??\",file=\"??\",fullname=\"??\",line=\"??\""
1266 const CMICmnMIValueConst miValueConst("??");
1267 const CMICmnMIValueResult miValueResult("addr", miValueConst);
1268 CMICmnMIValueTuple miValueTuple(miValueResult);
1269 const CMICmnMIValueResult miValueResult2("func", miValueConst);
1270 miValueTuple.Add(miValueResult2);
1271 const CMICmnMIValueResult miValueResult4("file", miValueConst);
1272 miValueTuple.Add(miValueResult4);
1273 const CMICmnMIValueResult miValueResult5("fullname", miValueConst);
1274 miValueTuple.Add(miValueResult5);
1275 const CMICmnMIValueResult miValueResult6("line", miValueConst);
1276 miValueTuple.Add(miValueResult6);
1278 vwrMiValueTuple = miValueTuple;
1280 return MIstatus::success;
1283 CMICmnMIValueTuple miValueTuple;
1284 if (!CMICmnLLDBDebugSessionInfo::Instance().MIResponseFormFrameInfo(
1285 thread, 0, CMICmnLLDBDebugSessionInfo::eFrameInfoFormat_NoArguments,
1287 SetErrorDescription(
1288 CMIUtilString::Format(MIRSRC(IDS_LLDBOUTOFBAND_ERR_FORM_MI_RESPONSE),
1289 "MiHelpGetCurrentThreadFrame()"));
1290 return MIstatus::failure;
1293 vwrMiValueTuple = miValueTuple;
1295 return MIstatus::success;
1299 //------------------------------------------------------------------------------------
1300 // Details: Asynchronous event handler for LLDB Process stop reason breakpoint.
1303 // Return: MIstatus::success - Functionality succeeded.
1304 // MIstatus::failure - Functionality failed.
1307 bool CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStopReasonBreakpoint() {
1308 // CODETAG_DEBUG_SESSION_RUNNING_PROG_RECEIVED_SIGINT_PAUSE_PROGRAM
1309 if (!CMIDriver::Instance().SetDriverStateRunningNotDebugging()) {
1310 const CMIUtilString &rErrMsg(CMIDriver::Instance().GetErrorDescription());
1311 SetErrorDescription(CMIUtilString::Format(
1312 MIRSRC(IDS_LLDBOUTOFBAND_ERR_SETNEWDRIVERSTATE),
1313 "HandleProcessEventStopReasonBreakpoint()", rErrMsg.c_str()));
1314 return MIstatus::failure;
1317 lldb::SBProcess sbProcess =
1318 CMICmnLLDBDebugSessionInfo::Instance().GetProcess();
1319 const MIuint64 brkPtId =
1320 sbProcess.GetSelectedThread().GetStopReasonDataAtIndex(0);
1321 lldb::SBBreakpoint brkPt =
1322 CMICmnLLDBDebugSessionInfo::Instance().GetTarget().GetBreakpointAtIndex(
1325 return MiStoppedAtBreakPoint(brkPtId, brkPt);
1329 //------------------------------------------------------------------------------------
1330 // Details: Form the MI Out-of-band response for stopped reason on hitting a
1333 // Args: vBrkPtId - (R) The LLDB break point's ID
1334 // vBrkPt - (R) THe LLDB break point object.
1335 // Return: MIstatus::success - Functionality succeeded.
1336 // MIstatus::failure - Functionality failed.
1339 bool CMICmnLLDBDebuggerHandleEvents::MiStoppedAtBreakPoint(
1340 const MIuint64 vBrkPtId, const lldb::SBBreakpoint &vBrkPt) {
1341 bool bOk = MIstatus::success;
1343 lldb::SBProcess sbProcess =
1344 CMICmnLLDBDebugSessionInfo::Instance().GetProcess();
1345 lldb::SBThread thread = sbProcess.GetSelectedThread();
1346 const MIuint nFrame = thread.GetNumFrames();
1349 // "*stopped,reason=\"breakpoint-hit\",disp=\"del\",bkptno=\"%d\",frame={},thread-id=\"%d\",stopped-threads=\"all\""
1350 const CMICmnMIValueConst miValueConst("breakpoint-hit");
1351 const CMICmnMIValueResult miValueResult("reason", miValueConst);
1352 CMICmnMIOutOfBandRecord miOutOfBandRecord(
1353 CMICmnMIOutOfBandRecord::eOutOfBand_Stopped, miValueResult);
1354 const CMICmnMIValueConst miValueConst2("del");
1355 const CMICmnMIValueResult miValueResult2("disp", miValueConst2);
1356 miOutOfBandRecord.Add(miValueResult2);
1357 const CMIUtilString strBkp(CMIUtilString::Format("%d", vBrkPtId));
1358 const CMICmnMIValueConst miValueConst3(strBkp);
1359 CMICmnMIValueResult miValueResult3("bkptno", miValueConst3);
1360 miOutOfBandRecord.Add(miValueResult3);
1361 const CMICmnMIValueConst miValueConst4("{}");
1362 const CMICmnMIValueResult miValueResult4("frame", miValueConst4);
1363 miOutOfBandRecord.Add(miValueResult4);
1364 const CMIUtilString strThreadId(
1365 CMIUtilString::Format("%d", vBrkPt.GetThreadIndex()));
1366 const CMICmnMIValueConst miValueConst5(strThreadId);
1367 const CMICmnMIValueResult miValueResult5("thread-id", miValueConst5);
1368 miOutOfBandRecord.Add(miValueResult5);
1369 const CMICmnMIValueConst miValueConst6("all");
1370 const CMICmnMIValueResult miValueResult6("stopped-threads", miValueConst6);
1371 miOutOfBandRecord.Add(miValueResult6);
1372 bOk = bOk && MiOutOfBandRecordToStdout(miOutOfBandRecord);
1373 bOk = bOk && CMICmnStreamStdout::WritePrompt();
1377 CMICmnLLDBDebugSessionInfo &rSessionInfo(
1378 CMICmnLLDBDebugSessionInfo::Instance());
1381 // "*stopped,reason=\"breakpoint-hit\",disp=\"del\",bkptno=\"%d\",frame={addr=\"0x%016"
1383 // "\",func=\"%s\",args=[],file=\"%s\",fullname=\"%s\",line=\"%d\"},thread-id=\"%d\",stopped-threads=\"all\""
1384 const CMICmnMIValueConst miValueConst("breakpoint-hit");
1385 const CMICmnMIValueResult miValueResult("reason", miValueConst);
1386 CMICmnMIOutOfBandRecord miOutOfBandRecord(
1387 CMICmnMIOutOfBandRecord::eOutOfBand_Stopped, miValueResult);
1388 const CMICmnMIValueConst miValueConstA("del");
1389 const CMICmnMIValueResult miValueResultA("disp", miValueConstA);
1390 miOutOfBandRecord.Add(miValueResultA);
1391 const CMIUtilString strBkp(CMIUtilString::Format("%d", vBrkPtId));
1392 const CMICmnMIValueConst miValueConstB(strBkp);
1393 CMICmnMIValueResult miValueResultB("bkptno", miValueConstB);
1394 miOutOfBandRecord.Add(miValueResultB);
1396 // frame={addr=\"0x%016" PRIx64
1397 // "\",func=\"%s\",args=[],file=\"%s\",fullname=\"%s\",line=\"%d\"}
1399 CMICmnMIValueTuple miValueTuple;
1401 rSessionInfo.MIResponseFormFrameInfo(
1403 CMICmnLLDBDebugSessionInfo::eFrameInfoFormat_AllArguments,
1405 const CMICmnMIValueResult miValueResult8("frame", miValueTuple);
1406 miOutOfBandRecord.Add(miValueResult8);
1409 // Add to MI thread-id=\"%d\",stopped-threads=\"all\"
1411 const CMIUtilString strThreadId(
1412 CMIUtilString::Format("%d", thread.GetIndexID()));
1413 const CMICmnMIValueConst miValueConst8(strThreadId);
1414 const CMICmnMIValueResult miValueResult8("thread-id", miValueConst8);
1415 miOutOfBandRecord.Add(miValueResult8);
1418 const CMICmnMIValueConst miValueConst9("all");
1419 const CMICmnMIValueResult miValueResult9("stopped-threads", miValueConst9);
1420 miOutOfBandRecord.Add(miValueResult9);
1421 bOk = MiOutOfBandRecordToStdout(miOutOfBandRecord);
1422 bOk = bOk && CMICmnStreamStdout::WritePrompt();
1425 return MIstatus::success;
1429 //------------------------------------------------------------------------------------
1430 // Details: Asynchronous event handler for LLDB Process stop reason trace.
1433 // Return: MIstatus::success - Functionality succeeded.
1434 // MIstatus::failure - Functionality failed.
1437 bool CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStopReasonTrace() {
1439 lldb::SBProcess sbProcess =
1440 CMICmnLLDBDebugSessionInfo::Instance().GetProcess();
1441 lldb::SBThread thread = sbProcess.GetSelectedThread();
1442 const MIuint nFrame = thread.GetNumFrames();
1444 // MI print "*stopped,reason=\"trace\",stopped-threads=\"all\""
1445 const CMICmnMIValueConst miValueConst("trace");
1446 const CMICmnMIValueResult miValueResult("reason", miValueConst);
1447 CMICmnMIOutOfBandRecord miOutOfBandRecord(
1448 CMICmnMIOutOfBandRecord::eOutOfBand_Stopped, miValueResult);
1449 const CMICmnMIValueConst miValueConst2("all");
1450 const CMICmnMIValueResult miValueResult2("stopped-threads", miValueConst2);
1451 miOutOfBandRecord.Add(miValueResult2);
1452 bOk = MiOutOfBandRecordToStdout(miOutOfBandRecord);
1453 bOk = bOk && CMICmnStreamStdout::WritePrompt();
1457 CMICmnLLDBDebugSessionInfo &rSessionInfo(
1458 CMICmnLLDBDebugSessionInfo::Instance());
1461 // "*stopped,reason=\"end-stepping-range\",frame={addr=\"0x%016" PRIx64
1462 // "\",func=\"%s\",args=[\"%s\"],file=\"%s\",fullname=\"%s\",line=\"%d\"},thread-id=\"%d\",stopped-threads=\"all\""
1465 CMICmnMIValueTuple miValueTuple;
1466 if (!rSessionInfo.MIResponseFormFrameInfo(
1467 thread, 0, CMICmnLLDBDebugSessionInfo::eFrameInfoFormat_AllArguments,
1469 return MIstatus::failure;
1471 const CMICmnMIValueConst miValueConst("end-stepping-range");
1472 const CMICmnMIValueResult miValueResult("reason", miValueConst);
1473 CMICmnMIOutOfBandRecord miOutOfBandRecord(
1474 CMICmnMIOutOfBandRecord::eOutOfBand_Stopped, miValueResult);
1475 const CMICmnMIValueResult miValueResult2("frame", miValueTuple);
1476 miOutOfBandRecord.Add(miValueResult2);
1478 // Add to MI thread-id=\"%d\",stopped-threads=\"all\"
1479 const CMIUtilString strThreadId(
1480 CMIUtilString::Format("%d", thread.GetIndexID()));
1481 const CMICmnMIValueConst miValueConst8(strThreadId);
1482 const CMICmnMIValueResult miValueResult8("thread-id", miValueConst8);
1483 miOutOfBandRecord.Add(miValueResult8);
1485 const CMICmnMIValueConst miValueConst9("all");
1486 const CMICmnMIValueResult miValueResult9("stopped-threads", miValueConst9);
1487 miOutOfBandRecord.Add(miValueResult9);
1488 bOk = MiOutOfBandRecordToStdout(miOutOfBandRecord);
1489 bOk = bOk && CMICmnStreamStdout::WritePrompt();
1495 //------------------------------------------------------------------------------------
1496 // Details: Asynchronous function update selected thread.
1499 // Return: MIstatus::success - Functionality succeeded.
1500 // MIstatus::failure - Functionality failed.
1503 bool CMICmnLLDBDebuggerHandleEvents::UpdateSelectedThread() {
1504 lldb::SBProcess process = CMICmnLLDBDebugSessionInfo::Instance()
1506 .GetSelectedTarget()
1508 if (!process.IsValid())
1509 return MIstatus::success;
1511 lldb::SBThread currentThread = process.GetSelectedThread();
1512 lldb::SBThread thread;
1513 const lldb::StopReason eCurrentThreadStoppedReason =
1514 currentThread.GetStopReason();
1515 if (!currentThread.IsValid() ||
1516 (eCurrentThreadStoppedReason == lldb::eStopReasonInvalid) ||
1517 (eCurrentThreadStoppedReason == lldb::eStopReasonNone)) {
1518 // Prefer a thread that has just completed its plan over another thread as
1520 lldb::SBThread planThread;
1521 lldb::SBThread otherThread;
1522 const size_t nThread = process.GetNumThreads();
1523 for (MIuint i = 0; i < nThread; i++) {
1524 // GetThreadAtIndex() uses a base 0 index
1525 // GetThreadByIndexID() uses a base 1 index
1526 thread = process.GetThreadAtIndex(i);
1527 const lldb::StopReason eThreadStopReason = thread.GetStopReason();
1528 switch (eThreadStopReason) {
1529 case lldb::eStopReasonTrace:
1530 case lldb::eStopReasonBreakpoint:
1531 case lldb::eStopReasonWatchpoint:
1532 case lldb::eStopReasonSignal:
1533 case lldb::eStopReasonException:
1534 if (!otherThread.IsValid())
1535 otherThread = thread;
1537 case lldb::eStopReasonPlanComplete:
1538 if (!planThread.IsValid())
1539 planThread = thread;
1541 case lldb::eStopReasonInvalid:
1542 case lldb::eStopReasonNone:
1547 if (planThread.IsValid())
1548 process.SetSelectedThread(planThread);
1549 else if (otherThread.IsValid())
1550 process.SetSelectedThread(otherThread);
1552 if (currentThread.IsValid())
1553 thread = currentThread;
1555 thread = process.GetThreadAtIndex(0);
1557 if (thread.IsValid())
1558 process.SetSelectedThread(thread);
1560 } // if( !currentThread.IsValid() || (eCurrentThreadStoppedReason ==
1561 // lldb::eStopReasonInvalid) || (eCurrentThreadStoppedReason ==
1562 // lldb::eStopReasonNone) )
1564 return MIstatus::success;
1568 //------------------------------------------------------------------------------------
1569 // Details: Print to stdout "*running,thread-id=\"all\"", "(gdb)".
1572 // Return: MIstatus::success - Functionality succeeded.
1573 // MIstatus::failure - Functionality failed.
1576 bool CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStateRunning() {
1577 CMICmnMIValueConst miValueConst("all");
1578 CMICmnMIValueResult miValueResult("thread-id", miValueConst);
1579 CMICmnMIOutOfBandRecord miOutOfBandRecord(
1580 CMICmnMIOutOfBandRecord::eOutOfBand_Running, miValueResult);
1581 bool bOk = MiOutOfBandRecordToStdout(miOutOfBandRecord);
1582 bOk = bOk && CMICmnStreamStdout::WritePrompt();
1588 //------------------------------------------------------------------------------------
1589 // Details: Print to stdout "=thread-exited,id=\"%ld\",group-id=\"i1\"",
1590 // "=thread-group-exited,id=\"i1\",exit-code=\"0\""),
1591 // "*stopped,reason=\"exited-normally\"",
1595 // Return: MIstatus::success - Functionality succeeded.
1596 // MIstatus::failure - Functionality failed.
1599 bool CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStateExited() {
1600 const CMIUtilString strId(CMIUtilString::Format("%ld", 1));
1601 CMICmnMIValueConst miValueConst(strId);
1602 CMICmnMIValueResult miValueResult("id", miValueConst);
1603 CMICmnMIOutOfBandRecord miOutOfBandRecord(
1604 CMICmnMIOutOfBandRecord::eOutOfBand_ThreadExited, miValueResult);
1605 CMICmnMIValueConst miValueConst2("i1");
1606 CMICmnMIValueResult miValueResult2("group-id", miValueConst2);
1607 miOutOfBandRecord.Add(miValueResult2);
1608 bool bOk = MiOutOfBandRecordToStdout(miOutOfBandRecord);
1610 CMICmnMIValueConst miValueConst3("i1");
1611 CMICmnMIValueResult miValueResult3("id", miValueConst3);
1612 CMICmnMIOutOfBandRecord miOutOfBandRecord2(
1613 CMICmnMIOutOfBandRecord::eOutOfBand_ThreadGroupExited, miValueResult3);
1614 CMICmnMIValueConst miValueConst2("0");
1615 CMICmnMIValueResult miValueResult2("exit-code", miValueConst2);
1616 miOutOfBandRecord2.Add(miValueResult2);
1617 bOk = bOk && MiOutOfBandRecordToStdout(miOutOfBandRecord2);
1620 CMICmnMIValueConst miValueConst4("exited-normally");
1621 CMICmnMIValueResult miValueResult4("reason", miValueConst4);
1622 CMICmnMIOutOfBandRecord miOutOfBandRecord3(
1623 CMICmnMIOutOfBandRecord::eOutOfBand_Stopped, miValueResult4);
1624 bOk = MiOutOfBandRecordToStdout(miOutOfBandRecord3);
1626 bOk = bOk && CMICmnStreamStdout::WritePrompt();
1632 //------------------------------------------------------------------------------------
1633 // Details: Drain all stdout so we don't see any output come after we print our
1635 // The process has stuff waiting for stdout; get it and write it out to
1637 // appropriate place.
1640 // Return: MIstatus::success - Functionality succeeded.
1641 // MIstatus::failure - Functionality failed.
1644 bool CMICmnLLDBDebuggerHandleEvents::GetProcessStdout() {
1646 std::unique_ptr<char[]> apStdoutBuffer(new char[1024]);
1647 lldb::SBProcess process = CMICmnLLDBDebugSessionInfo::Instance()
1649 .GetSelectedTarget()
1652 const size_t nBytes = process.GetSTDOUT(apStdoutBuffer.get(), 1024);
1653 text.append(apStdoutBuffer.get(), nBytes);
1656 const size_t nNewLine = text.find('\n');
1657 if (nNewLine == std::string::npos)
1660 const CMIUtilString line(text.substr(0, nNewLine + 1));
1661 text.erase(0, nNewLine + 1);
1662 const bool bEscapeQuotes(true);
1663 CMICmnMIValueConst miValueConst(line.Escape(bEscapeQuotes));
1664 CMICmnMIOutOfBandRecord miOutOfBandRecord(
1665 CMICmnMIOutOfBandRecord::eOutOfBand_TargetStreamOutput, miValueConst);
1666 const bool bOk = MiOutOfBandRecordToStdout(miOutOfBandRecord);
1668 return MIstatus::failure;
1672 if (!text.empty()) {
1673 const bool bEscapeQuotes(true);
1674 CMICmnMIValueConst miValueConst(text.Escape(bEscapeQuotes));
1675 CMICmnMIOutOfBandRecord miOutOfBandRecord(
1676 CMICmnMIOutOfBandRecord::eOutOfBand_TargetStreamOutput,
1678 return MiOutOfBandRecordToStdout(miOutOfBandRecord);
1684 return MIstatus::success;
1688 //------------------------------------------------------------------------------------
1689 // Details: Drain all stderr so we don't see any output come after we print our
1691 // The process has stuff waiting for stderr; get it and write it out to
1693 // appropriate place.
1696 // Return: MIstatus::success - Functionality succeeded.
1697 // MIstatus::failure - Functionality failed.
1700 bool CMICmnLLDBDebuggerHandleEvents::GetProcessStderr() {
1702 std::unique_ptr<char[]> apStderrBuffer(new char[1024]);
1703 lldb::SBProcess process = CMICmnLLDBDebugSessionInfo::Instance()
1705 .GetSelectedTarget()
1708 const size_t nBytes = process.GetSTDERR(apStderrBuffer.get(), 1024);
1709 text.append(apStderrBuffer.get(), nBytes);
1712 const size_t nNewLine = text.find('\n');
1713 if (nNewLine == std::string::npos)
1716 const CMIUtilString line(text.substr(0, nNewLine + 1));
1717 const bool bEscapeQuotes(true);
1718 CMICmnMIValueConst miValueConst(line.Escape(bEscapeQuotes));
1719 CMICmnMIOutOfBandRecord miOutOfBandRecord(
1720 CMICmnMIOutOfBandRecord::eOutOfBand_TargetStreamOutput, miValueConst);
1721 const bool bOk = MiOutOfBandRecordToStdout(miOutOfBandRecord);
1723 return MIstatus::failure;
1727 if (!text.empty()) {
1728 const bool bEscapeQuotes(true);
1729 CMICmnMIValueConst miValueConst(text.Escape(bEscapeQuotes));
1730 CMICmnMIOutOfBandRecord miOutOfBandRecord(
1731 CMICmnMIOutOfBandRecord::eOutOfBand_TargetStreamOutput,
1733 return MiOutOfBandRecordToStdout(miOutOfBandRecord);
1739 return MIstatus::success;
1743 //------------------------------------------------------------------------------------
1744 // Details: Asynchronous event function check for state changes.
1747 // Return: MIstatus::success - Functionality succeeded.
1748 // MIstatus::failure - Functionality failed.
1751 bool CMICmnLLDBDebuggerHandleEvents::ChkForStateChanges() {
1752 CMICmnLLDBDebugSessionInfo &rSessionInfo(
1753 CMICmnLLDBDebugSessionInfo::Instance());
1754 lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
1755 if (!sbProcess.IsValid())
1756 return MIstatus::success;
1758 // Check for created threads
1759 const MIuint nThread = sbProcess.GetNumThreads();
1760 for (MIuint i = 0; i < nThread; i++) {
1761 // GetThreadAtIndex() uses a base 0 index
1762 // GetThreadByIndexID() uses a base 1 index
1763 lldb::SBThread thread = sbProcess.GetThreadAtIndex(i);
1764 if (!thread.IsValid())
1767 const MIuint threadIndexID = thread.GetIndexID();
1769 std::find(rSessionInfo.m_vecActiveThreadId.cbegin(),
1770 rSessionInfo.m_vecActiveThreadId.cend(),
1771 threadIndexID) != rSessionInfo.m_vecActiveThreadId.end();
1773 rSessionInfo.m_vecActiveThreadId.push_back(threadIndexID);
1775 // Form MI "=thread-created,id=\"%d\",group-id=\"i1\""
1776 const CMIUtilString strValue(CMIUtilString::Format("%d", threadIndexID));
1777 const CMICmnMIValueConst miValueConst(strValue);
1778 const CMICmnMIValueResult miValueResult("id", miValueConst);
1779 CMICmnMIOutOfBandRecord miOutOfBand(
1780 CMICmnMIOutOfBandRecord::eOutOfBand_ThreadCreated, miValueResult);
1781 const CMICmnMIValueConst miValueConst2("i1");
1782 const CMICmnMIValueResult miValueResult2("group-id", miValueConst2);
1783 miOutOfBand.Add(miValueResult2);
1784 bool bOk = MiOutOfBandRecordToStdout(miOutOfBand);
1786 return MIstatus::failure;
1790 lldb::SBThread currentThread = sbProcess.GetSelectedThread();
1791 if (currentThread.IsValid()) {
1792 const MIuint currentThreadIndexID = currentThread.GetIndexID();
1793 if (rSessionInfo.m_currentSelectedThread != currentThreadIndexID) {
1794 rSessionInfo.m_currentSelectedThread = currentThreadIndexID;
1796 // Form MI "=thread-selected,id=\"%d\""
1797 const CMIUtilString strValue(
1798 CMIUtilString::Format("%d", currentThreadIndexID));
1799 const CMICmnMIValueConst miValueConst(strValue);
1800 const CMICmnMIValueResult miValueResult("id", miValueConst);
1801 CMICmnMIOutOfBandRecord miOutOfBand(
1802 CMICmnMIOutOfBandRecord::eOutOfBand_ThreadSelected, miValueResult);
1803 if (!MiOutOfBandRecordToStdout(miOutOfBand))
1804 return MIstatus::failure;
1808 // Check for invalid (removed) threads
1809 CMICmnLLDBDebugSessionInfo::VecActiveThreadId_t::iterator it =
1810 rSessionInfo.m_vecActiveThreadId.begin();
1811 while (it != rSessionInfo.m_vecActiveThreadId.end()) {
1812 const MIuint threadIndexID = *it;
1813 lldb::SBThread thread = sbProcess.GetThreadByIndexID(threadIndexID);
1814 if (!thread.IsValid()) {
1815 // Form MI "=thread-exited,id=\"%ld\",group-id=\"i1\""
1816 const CMIUtilString strValue(CMIUtilString::Format("%ld", threadIndexID));
1817 const CMICmnMIValueConst miValueConst(strValue);
1818 const CMICmnMIValueResult miValueResult("id", miValueConst);
1819 CMICmnMIOutOfBandRecord miOutOfBand(
1820 CMICmnMIOutOfBandRecord::eOutOfBand_ThreadExited, miValueResult);
1821 const CMICmnMIValueConst miValueConst2("i1");
1822 const CMICmnMIValueResult miValueResult2("group-id", miValueConst2);
1823 miOutOfBand.Add(miValueResult2);
1824 bool bOk = MiOutOfBandRecordToStdout(miOutOfBand);
1826 return MIstatus::failure;
1828 // Remove current thread from cache and get next
1829 it = rSessionInfo.m_vecActiveThreadId.erase(it);
1835 return CMICmnStreamStdout::WritePrompt();
1839 //------------------------------------------------------------------------------------
1840 // Details: Take a fully formed MI result record and send to the stdout stream.
1841 // Also output to the MI Log file.
1843 // Args: vrMiResultRecord - (R) MI result record object.
1844 // Return: MIstatus::success - Functionality succeeded.
1845 // MIstatus::failure - Functionality failed.
1848 bool CMICmnLLDBDebuggerHandleEvents::MiResultRecordToStdout(
1849 const CMICmnMIResultRecord &vrMiResultRecord) {
1850 return TextToStdout(vrMiResultRecord.GetString());
1854 //------------------------------------------------------------------------------------
1855 // Details: Take a fully formed MI Out-of-band record and send to the stdout
1857 // Also output to the MI Log file.
1859 // Args: vrMiOutOfBandRecord - (R) MI Out-of-band record object.
1860 // Return: MIstatus::success - Functionality succeeded.
1861 // MIstatus::failure - Functionality failed.
1864 bool CMICmnLLDBDebuggerHandleEvents::MiOutOfBandRecordToStdout(
1865 const CMICmnMIOutOfBandRecord &vrMiOutOfBandRecord) {
1866 return TextToStdout(vrMiOutOfBandRecord.GetString());
1870 //------------------------------------------------------------------------------------
1871 // Details: Take a text data and send to the stdout stream. Also output to the
1875 // Args: vrTxt - (R) Text.
1876 // Return: MIstatus::success - Functionality succeeded.
1877 // MIstatus::failure - Functionality failed.
1880 bool CMICmnLLDBDebuggerHandleEvents::TextToStdout(const CMIUtilString &vrTxt) {
1881 return CMICmnStreamStdout::TextToStdout(vrTxt);
1885 //------------------------------------------------------------------------------------
1886 // Details: Take a text data and send to the stderr stream. Also output to the
1890 // Args: vrTxt - (R) Text.
1891 // Return: MIstatus::success - Functionality succeeded.
1892 // MIstatus::failure - Functionality failed.
1895 bool CMICmnLLDBDebuggerHandleEvents::TextToStderr(const CMIUtilString &vrTxt) {
1896 return CMICmnStreamStderr::TextToStderr(vrTxt);
1900 //------------------------------------------------------------------------------------
1901 // Details: Initialize the member variables with the signal values in this
1909 void CMICmnLLDBDebuggerHandleEvents::InitializeSignals() {
1910 if (!m_bSignalsInitialized) {
1911 lldb::SBProcess sbProcess =
1912 CMICmnLLDBDebugSessionInfo::Instance().GetProcess();
1913 if (sbProcess.IsValid()) {
1914 lldb::SBUnixSignals unix_signals = sbProcess.GetUnixSignals();
1915 m_SIGINT = unix_signals.GetSignalNumberFromName("SIGINT");
1916 m_SIGSTOP = unix_signals.GetSignalNumberFromName("SIGSTOP");
1917 m_SIGSEGV = unix_signals.GetSignalNumberFromName("SIGSEGV");
1918 m_SIGTRAP = unix_signals.GetSignalNumberFromName("SIGTRAP");
1919 m_bSignalsInitialized = true;