1 //===-- MICmnLLDBDebugger.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 //===----------------------------------------------------------------------===//
11 // File: MICmnLLDBDebugger.cpp
13 // Overview: CMICmnLLDBDebugger implementation.
15 // Environment: Compilers: Visual C++ 12.
16 // gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
17 // Libraries: See MIReadmetxt.
22 // Third party headers:
23 #include <lldb/API/SBTarget.h>
24 #include <lldb/API/SBThread.h>
25 #include <lldb/API/SBProcess.h>
26 #include <lldb/API/SBCommandInterpreter.h>
29 #include "MICmnLLDBDebugger.h"
30 #include "MICmnResources.h"
32 #include "MIDriverBase.h"
33 #include "MICmnThreadMgrStd.h"
34 #include "MICmnLLDBDebuggerHandleEvents.h"
35 #include "MICmnLLDBDebugSessionInfo.h"
36 #include "MIUtilSingletonHelper.h"
38 //++ ------------------------------------------------------------------------------------
39 // Details: CMICmnLLDBDebugger constructor.
45 CMICmnLLDBDebugger::CMICmnLLDBDebugger(void)
46 : m_constStrThisThreadId("MI debugger event")
50 //++ ------------------------------------------------------------------------------------
51 // Details: CMICmnLLDBDebugger destructor.
57 CMICmnLLDBDebugger::~CMICmnLLDBDebugger(void)
62 //++ ------------------------------------------------------------------------------------
63 // Details: Initialize resources for *this debugger object.
66 // Return: MIstatus::success - Functionality succeeded.
67 // MIstatus::failure - Functionality failed.
71 CMICmnLLDBDebugger::Initialize(void)
73 m_clientUsageRefCnt++;
76 return MIstatus::success;
78 bool bOk = MIstatus::success;
80 ClrErrorDescription();
82 if (m_pClientDriver == nullptr)
85 errMsg = MIRSRC(IDS_LLDBDEBUGGER_ERR_CLIENTDRIVER);
88 // Note initialization order is important here as some resources depend on previous
89 MI::ModuleInit<CMICmnLog>(IDS_MI_INIT_ERR_LOG, bOk, errMsg);
90 MI::ModuleInit<CMICmnResources>(IDS_MI_INIT_ERR_RESOURCES, bOk, errMsg);
91 MI::ModuleInit<CMICmnThreadMgrStd>(IDS_MI_INIT_ERR_THREADMGR, bOk, errMsg);
92 MI::ModuleInit<CMICmnLLDBDebuggerHandleEvents>(IDS_MI_INIT_ERR_OUTOFBANDHANDLER, bOk, errMsg);
93 MI::ModuleInit<CMICmnLLDBDebugSessionInfo>(IDS_MI_INIT_ERR_DEBUGSESSIONINFO, bOk, errMsg);
95 // Note order is important here!
97 lldb::SBDebugger::Initialize();
98 if (bOk && !InitSBDebugger())
103 errMsg += GetErrorDescription().c_str();
105 if (bOk && !InitSBListener())
110 errMsg += GetErrorDescription().c_str();
112 bOk = bOk && InitStdStreams();
114 m_bInitialized = bOk;
116 if (!bOk && !HaveErrorDescription())
118 CMIUtilString strInitError(CMIUtilString::Format(MIRSRC(IDS_MI_INIT_ERR_LLDBDEBUGGER), errMsg.c_str()));
119 SetErrorDescription(strInitError);
125 //++ ------------------------------------------------------------------------------------
126 // Details: Release resources for *this debugger object.
129 // Return: MIstatus::success - Functionality succeeded.
130 // MIstatus::failure - Functionality failed.
134 CMICmnLLDBDebugger::Shutdown(void)
136 if (--m_clientUsageRefCnt > 0)
137 return MIstatus::success;
140 return MIstatus::success;
142 m_bInitialized = false;
144 ClrErrorDescription();
146 bool bOk = MIstatus::success;
147 CMIUtilString errMsg;
149 // Explicitly delete the remote target in case MI needs to exit prematurely otherwise
150 // LLDB debugger may hang in its Destroy() fn waiting on events
151 m_lldbDebugger.DeleteTarget(CMICmnLLDBDebugSessionInfo::Instance().m_lldbTarget);
153 // Debug: May need this but does seem to work without it so commented out the fudge 19/06/2014
154 // It appears we need to wait as hang does not occur when hitting a debug breakpoint here
155 // const std::chrono::milliseconds time( 1000 );
156 // std::this_thread::sleep_for( time );
158 lldb::SBDebugger::Destroy(m_lldbDebugger);
159 lldb::SBDebugger::Terminate();
160 m_pClientDriver = nullptr;
161 m_mapBroadcastClassNameToEventMask.clear();
162 m_mapIdToEventMask.clear();
164 // Note shutdown order is important here
165 MI::ModuleShutdown<CMICmnLLDBDebugSessionInfo>(IDS_MI_INIT_ERR_DEBUGSESSIONINFO, bOk, errMsg);
166 MI::ModuleShutdown<CMICmnLLDBDebuggerHandleEvents>(IDS_MI_INIT_ERR_OUTOFBANDHANDLER, bOk, errMsg);
167 MI::ModuleShutdown<CMICmnThreadMgrStd>(IDS_MI_INIT_ERR_THREADMGR, bOk, errMsg);
168 MI::ModuleShutdown<CMICmnResources>(IDS_MI_INIT_ERR_RESOURCES, bOk, errMsg);
169 MI::ModuleShutdown<CMICmnLog>(IDS_MI_INIT_ERR_LOG, bOk, errMsg);
173 SetErrorDescriptionn(MIRSRC(IDS_MI_SHTDWN_ERR_LLDBDEBUGGER), errMsg.c_str());
176 return MIstatus::success;
179 //++ ------------------------------------------------------------------------------------
180 // Details: Return the LLDB debugger instance created for this debug session.
183 // Return: lldb::SBDebugger & - LLDB debugger object reference.
187 CMICmnLLDBDebugger::GetTheDebugger(void)
189 return m_lldbDebugger;
192 //++ ------------------------------------------------------------------------------------
193 // Details: Return the LLDB listener instance created for this debug session.
196 // Return: lldb::SBListener & - LLDB listener object reference.
200 CMICmnLLDBDebugger::GetTheListener(void)
202 return m_lldbListener;
205 //++ ------------------------------------------------------------------------------------
206 // Details: Set the client driver that wants to use *this LLDB debugger. Call this function
207 // prior to Initialize().
209 // Args: vClientDriver - (R) A driver.
210 // Return: MIstatus::success - Functionality succeeded.
211 // MIstatus::failure - Functionality failed.
215 CMICmnLLDBDebugger::SetDriver(const CMIDriverBase &vClientDriver)
217 m_pClientDriver = const_cast<CMIDriverBase *>(&vClientDriver);
219 return MIstatus::success;
222 //++ ------------------------------------------------------------------------------------
223 // Details: Get the client driver that is use *this LLDB debugger.
225 // Args: vClientDriver - (R) A driver.
226 // Return: CMIDriverBase & - A driver instance.
230 CMICmnLLDBDebugger::GetDriver(void) const
232 return *m_pClientDriver;
235 //++ ------------------------------------------------------------------------------------
236 // Details: Initialize the LLDB Debugger object.
239 // Return: MIstatus::success - Functionality succeeded.
240 // MIstatus::failure - Functionality failed.
244 CMICmnLLDBDebugger::InitSBDebugger(void)
246 m_lldbDebugger = lldb::SBDebugger::Create(false);
247 if (m_lldbDebugger.IsValid())
248 return MIstatus::success;
250 SetErrorDescription(MIRSRC(IDS_LLDBDEBUGGER_ERR_INVALIDDEBUGGER));
251 return MIstatus::failure;
254 //++ ------------------------------------------------------------------------------------
255 // Details: Set the LLDB Debugger's std in, err and out streams. (Not implemented left
256 // here for reference. Was called in the CMICmnLLDBDebugger::Initialize() )
259 // Return: MIstatus::success - Functionality succeeded.
260 // MIstatus::failure - Functionality failed.
264 CMICmnLLDBDebugger::InitStdStreams(void)
266 // This is not required when operating the MI driver's code as it has its own
267 // streams. Setting the Stdin for the lldbDebugger especially on LINUX will cause
268 // another thread to run and partially consume stdin data meant for MI stdin handler
269 // m_lldbDebugger.SetErrorFileHandle( m_pClientDriver->GetStderr(), false );
270 // m_lldbDebugger.SetOutputFileHandle( m_pClientDriver->GetStdout(), false );
271 // m_lldbDebugger.SetInputFileHandle( m_pClientDriver->GetStdin(), false );
273 return MIstatus::success;
276 //++ ------------------------------------------------------------------------------------
277 // Details: Set up the events from the SBDebugger's we would to listent to.
280 // Return: MIstatus::success - Functionality succeeded.
281 // MIstatus::failure - Functionality failed.
285 CMICmnLLDBDebugger::InitSBListener(void)
287 m_lldbListener = m_lldbDebugger.GetListener();
288 if (!m_lldbListener.IsValid())
290 SetErrorDescription(MIRSRC(IDS_LLDBDEBUGGER_ERR_INVALIDLISTENER));
291 return MIstatus::failure;
294 const CMIUtilString strDbgId("CMICmnLLDBDebugger1");
295 MIuint eventMask = lldb::SBTarget::eBroadcastBitBreakpointChanged;
296 bool bOk = RegisterForEvent(strDbgId, CMIUtilString(lldb::SBTarget::GetBroadcasterClassName()), eventMask);
298 eventMask = lldb::SBThread::eBroadcastBitStackChanged;
299 bOk = bOk && RegisterForEvent(strDbgId, CMIUtilString(lldb::SBThread::GetBroadcasterClassName()), eventMask);
301 eventMask = lldb::SBProcess::eBroadcastBitStateChanged | lldb::SBProcess::eBroadcastBitInterrupt |
302 lldb::SBProcess::eBroadcastBitSTDOUT | lldb::SBProcess::eBroadcastBitSTDERR | lldb::SBProcess::eBroadcastBitProfileData;
303 bOk = bOk && RegisterForEvent(strDbgId, CMIUtilString(lldb::SBProcess::GetBroadcasterClassName()), eventMask);
305 eventMask = lldb::SBCommandInterpreter::eBroadcastBitQuitCommandReceived | lldb::SBCommandInterpreter::eBroadcastBitThreadShouldExit |
306 lldb::SBCommandInterpreter::eBroadcastBitAsynchronousOutputData |
307 lldb::SBCommandInterpreter::eBroadcastBitAsynchronousErrorData;
308 bOk = bOk && RegisterForEvent(strDbgId, CMIUtilString(lldb::SBCommandInterpreter::GetBroadcasterClass()), eventMask);
313 //++ ------------------------------------------------------------------------------------
314 // Details: Register with the debugger, the SBListener, the type of events you are interested
315 // in. Others, like commands, may have already set the mask.
317 // Args: vClientName - (R) ID of the client who wants these events set.
318 // vBroadcasterClass - (R) The SBBroadcaster's class name.
319 // vEventMask - (R) The mask of events to listen for.
320 // Return: MIstatus::success - Functionality succeeded.
321 // MIstatus::failure - Functionality failed.
325 CMICmnLLDBDebugger::RegisterForEvent(const CMIUtilString &vClientName, const CMIUtilString &vBroadcasterClass, const MIuint vEventMask)
327 MIuint existingMask = 0;
328 if (!BroadcasterGetMask(vBroadcasterClass, existingMask))
329 return MIstatus::failure;
331 if (!ClientSaveMask(vClientName, vBroadcasterClass, vEventMask))
332 return MIstatus::failure;
334 const MIchar *pBroadCasterName = vBroadcasterClass.c_str();
335 MIuint eventMask = vEventMask;
336 eventMask += existingMask;
337 const MIuint result = m_lldbListener.StartListeningForEventClass(m_lldbDebugger, pBroadCasterName, eventMask);
340 SetErrorDescription(CMIUtilString::Format(MIRSRC(IDS_LLDBDEBUGGER_ERR_STARTLISTENER), pBroadCasterName));
341 return MIstatus::failure;
344 return BroadcasterSaveMask(vBroadcasterClass, eventMask);
347 //++ ------------------------------------------------------------------------------------
348 // Details: Register with the debugger, the SBListener, the type of events you are interested
349 // in. Others, like commands, may have already set the mask.
351 // Args: vClientName - (R) ID of the client who wants these events set.
352 // vBroadcaster - (R) An SBBroadcaster's derived class.
353 // vEventMask - (R) The mask of events to listen for.
354 // Return: MIstatus::success - Functionality succeeded.
355 // MIstatus::failure - Functionality failed.
359 CMICmnLLDBDebugger::RegisterForEvent(const CMIUtilString &vClientName, const lldb::SBBroadcaster &vBroadcaster, const MIuint vEventMask)
361 const MIchar *pBroadcasterName = vBroadcaster.GetName();
362 if (pBroadcasterName == nullptr)
364 SetErrorDescription(CMIUtilString::Format(MIRSRC(IDS_LLDBDEBUGGER_ERR_BROARDCASTER_NAME), MIRSRC(IDS_WORD_INVALIDNULLPTR)));
365 return MIstatus::failure;
367 CMIUtilString broadcasterName(pBroadcasterName);
368 if (broadcasterName.length() == 0)
370 SetErrorDescription(CMIUtilString::Format(MIRSRC(IDS_LLDBDEBUGGER_ERR_BROARDCASTER_NAME), MIRSRC(IDS_WORD_INVALIDEMPTY)));
371 return MIstatus::failure;
374 MIuint existingMask = 0;
375 if (!BroadcasterGetMask(broadcasterName, existingMask))
376 return MIstatus::failure;
378 if (!ClientSaveMask(vClientName, broadcasterName, vEventMask))
379 return MIstatus::failure;
381 MIuint eventMask = vEventMask;
382 eventMask += existingMask;
383 const MIuint result = m_lldbListener.StartListeningForEvents(vBroadcaster, eventMask);
386 SetErrorDescription(CMIUtilString::Format(MIRSRC(IDS_LLDBDEBUGGER_ERR_STARTLISTENER), pBroadcasterName));
387 return MIstatus::failure;
390 return BroadcasterSaveMask(broadcasterName, eventMask);
393 //++ ------------------------------------------------------------------------------------
394 // Details: Unregister with the debugger, the SBListener, the type of events you are no
395 // longer interested in. Others, like commands, may still remain interested so
396 // an event may not necessarily be stopped.
398 // Args: vClientName - (R) ID of the client who no longer requires these events.
399 // vBroadcasterClass - (R) The SBBroadcaster's class name.
400 // Return: MIstatus::success - Functionality succeeded.
401 // MIstatus::failure - Functionality failed.
405 CMICmnLLDBDebugger::UnregisterForEvent(const CMIUtilString &vClientName, const CMIUtilString &vBroadcasterClass)
407 MIuint clientsEventMask = 0;
408 if (!ClientGetTheirMask(vClientName, vBroadcasterClass, clientsEventMask))
409 return MIstatus::failure;
410 if (!ClientRemoveTheirMask(vClientName, vBroadcasterClass))
411 return MIstatus::failure;
413 const MIuint otherClientsEventMask = ClientGetMaskForAllClients(vBroadcasterClass);
414 MIuint newEventMask = 0;
415 for (MIuint i = 0; i < 32; i++)
417 const MIuint bit = 1 << i;
418 const MIuint clientBit = bit & clientsEventMask;
419 const MIuint othersBit = bit & otherClientsEventMask;
420 if ((clientBit != 0) && (othersBit == 0))
422 newEventMask += clientBit;
426 const MIchar *pBroadCasterName = vBroadcasterClass.c_str();
427 if (!m_lldbListener.StopListeningForEventClass(m_lldbDebugger, pBroadCasterName, newEventMask))
429 SetErrorDescription(CMIUtilString::Format(MIRSRC(IDS_LLDBDEBUGGER_ERR_STOPLISTENER), vClientName.c_str(), pBroadCasterName));
430 return MIstatus::failure;
433 return BroadcasterSaveMask(vBroadcasterClass, otherClientsEventMask);
436 //++ ------------------------------------------------------------------------------------
437 // Details: Given the SBBroadcaster class name retrieve it's current event mask.
439 // Args: vBroadcasterClass - (R) The SBBroadcaster's class name.
440 // vEventMask - (W) The mask of events to listen for.
441 // Return: MIstatus::success - Functionality succeeded.
442 // MIstatus::failure - Functionality failed.
446 CMICmnLLDBDebugger::BroadcasterGetMask(const CMIUtilString &vBroadcasterClass, MIuint &vwEventMask) const
450 if (vBroadcasterClass.empty())
452 SetErrorDescription(CMIUtilString::Format(MIRSRC(IDS_LLDBDEBUGGER_ERR_INVALIDBROADCASTER), vBroadcasterClass.c_str()));
453 return MIstatus::failure;
456 const MapBroadcastClassNameToEventMask_t::const_iterator it = m_mapBroadcastClassNameToEventMask.find(vBroadcasterClass);
457 if (it != m_mapBroadcastClassNameToEventMask.end())
459 vwEventMask = (*it).second;
462 return MIstatus::success;
465 //++ ------------------------------------------------------------------------------------
466 // Details: Remove the event mask for the specified SBBroadcaster class name.
468 // Args: vBroadcasterClass - (R) The SBBroadcaster's class name.
469 // Return: MIstatus::success - Functionality succeeded.
470 // MIstatus::failure - Functionality failed.
474 CMICmnLLDBDebugger::BroadcasterRemoveMask(const CMIUtilString &vBroadcasterClass)
476 MapBroadcastClassNameToEventMask_t::const_iterator it = m_mapBroadcastClassNameToEventMask.find(vBroadcasterClass);
477 if (it != m_mapBroadcastClassNameToEventMask.end())
479 m_mapBroadcastClassNameToEventMask.erase(it);
482 return MIstatus::success;
485 //++ ------------------------------------------------------------------------------------
486 // Details: Given the SBBroadcaster class name save it's current event mask.
488 // Args: vBroadcasterClass - (R) The SBBroadcaster's class name.
489 // vEventMask - (R) The mask of events to listen for.
490 // Return: MIstatus::success - Functionality succeeded.
491 // MIstatus::failure - Functionality failed.
495 CMICmnLLDBDebugger::BroadcasterSaveMask(const CMIUtilString &vBroadcasterClass, const MIuint vEventMask)
497 if (vBroadcasterClass.empty())
499 SetErrorDescription(CMIUtilString::Format(MIRSRC(IDS_LLDBDEBUGGER_ERR_INVALIDBROADCASTER), vBroadcasterClass.c_str()));
500 return MIstatus::failure;
503 BroadcasterRemoveMask(vBroadcasterClass);
504 MapPairBroadcastClassNameToEventMask_t pr(vBroadcasterClass, vEventMask);
505 m_mapBroadcastClassNameToEventMask.insert(pr);
507 return MIstatus::success;
510 //++ ------------------------------------------------------------------------------------
511 // Details: Iterate all the clients who have registered event masks against particular
512 // SBBroadcasters and build up the mask that is for all of them.
514 // Args: vBroadcasterClass - (R) The broadcaster to retrieve the mask for.
515 // Return: MIuint - Event mask.
519 CMICmnLLDBDebugger::ClientGetMaskForAllClients(const CMIUtilString &vBroadcasterClass) const
522 MapIdToEventMask_t::const_iterator it = m_mapIdToEventMask.begin();
523 while (it != m_mapIdToEventMask.end())
525 const CMIUtilString &rId((*it).first);
526 if (rId.find(vBroadcasterClass.c_str()) != std::string::npos)
528 const MIuint clientsMask = (*it).second;
539 //++ ------------------------------------------------------------------------------------
540 // Details: Given the client save its particular event requirements.
542 // Args: vClientName - (R) The Client's unique ID.
543 // vBroadcasterClass - (R) The SBBroadcaster's class name targeted for the events.
544 // vEventMask - (R) The mask of events to listen for.
545 // Return: MIstatus::success - Functionality succeeded.
546 // MIstatus::failure - Functionality failed.
550 CMICmnLLDBDebugger::ClientSaveMask(const CMIUtilString &vClientName, const CMIUtilString &vBroadcasterClass, const MIuint vEventMask)
552 if (vClientName.empty())
554 SetErrorDescription(CMIUtilString::Format(MIRSRC(IDS_LLDBDEBUGGER_ERR_INVALIDCLIENTNAME), vClientName.c_str()));
555 return MIstatus::failure;
558 CMIUtilString strId(vBroadcasterClass);
559 strId += vClientName;
561 ClientRemoveTheirMask(vClientName, vBroadcasterClass);
562 MapPairIdToEventMask_t pr(strId, vEventMask);
563 m_mapIdToEventMask.insert(pr);
565 return MIstatus::success;
568 //++ ------------------------------------------------------------------------------------
569 // Details: Given the client remove it's particular event requirements.
571 // Args: vClientName - (R) The Client's unique ID.
572 // vBroadcasterClass - (R) The SBBroadcaster's class name.
573 // Return: MIstatus::success - Functionality succeeded.
574 // MIstatus::failure - Functionality failed.
578 CMICmnLLDBDebugger::ClientRemoveTheirMask(const CMIUtilString &vClientName, const CMIUtilString &vBroadcasterClass)
580 if (vClientName.empty())
582 SetErrorDescription(CMIUtilString::Format(MIRSRC(IDS_LLDBDEBUGGER_ERR_INVALIDCLIENTNAME), vClientName.c_str()));
583 return MIstatus::failure;
586 CMIUtilString strId(vBroadcasterClass);
587 strId += vClientName;
589 const MapIdToEventMask_t::const_iterator it = m_mapIdToEventMask.find(strId);
590 if (it != m_mapIdToEventMask.end())
592 m_mapIdToEventMask.erase(it);
595 return MIstatus::success;
598 //++ ------------------------------------------------------------------------------------
599 // Details: Retrieve the client's event mask used for on a particular SBBroadcaster.
601 // Args: vClientName - (R) The Client's unique ID.
602 // vBroadcasterClass - (R) The SBBroadcaster's class name.
603 // vwEventMask - (W) The client's mask.
604 // Return: MIstatus::success - Functionality succeeded.
605 // MIstatus::failure - Functionality failed.
609 CMICmnLLDBDebugger::ClientGetTheirMask(const CMIUtilString &vClientName, const CMIUtilString &vBroadcasterClass, MIuint &vwEventMask)
613 if (vClientName.empty())
615 SetErrorDescription(CMIUtilString::Format(MIRSRC(IDS_LLDBDEBUGGER_ERR_INVALIDCLIENTNAME), vClientName.c_str()));
616 return MIstatus::failure;
619 CMIUtilString strId(vBroadcasterClass.c_str());
620 strId += vClientName;
622 const MapIdToEventMask_t::const_iterator it = m_mapIdToEventMask.find(strId);
623 if (it != m_mapIdToEventMask.end())
625 vwEventMask = (*it).second;
628 SetErrorDescription(CMIUtilString::Format(MIRSRC(IDS_LLDBDEBUGGER_ERR_CLIENTNOTREGISTERD), vClientName.c_str()));
630 return MIstatus::failure;
633 //++ ------------------------------------------------------------------------------------
634 // Details: Momentarily wait for an events being broadcast and inspect those that do
635 // come this way. Check if the target should exit event if so start shutting
636 // down this thread and the application. Any other events pass on to the
637 // Out-of-band handler to futher determine what kind of event arrived.
638 // This function runs in the thread "MI debugger event".
640 // Args: vrbIsAlive - (W) False = yes exit event monitoring thread, true = continue.
641 // Return: MIstatus::success - Functional succeeded.
642 // MIstatus::failure - Functional failed.
646 CMICmnLLDBDebugger::MonitorSBListenerEvents(bool &vrbIsAlive)
651 const bool bGotEvent = m_lldbListener.GetNextEvent(event);
652 if (!bGotEvent || !event.IsValid())
654 const std::chrono::milliseconds time(1);
655 std::this_thread::sleep_for(time);
656 return MIstatus::success;
658 if (!event.GetBroadcaster().IsValid())
659 return MIstatus::success;
662 m_pLog->WriteLog(CMIUtilString::Format("##### An event occurred: %s", event.GetBroadcasterClass()));
664 bool bHandledEvent = false;
665 bool bExitAppEvent = false;
666 const bool bOk = CMICmnLLDBDebuggerHandleEvents::Instance().HandleEvent(event, bHandledEvent, bExitAppEvent);
669 const CMIUtilString msg(CMIUtilString::Format(MIRSRC(IDS_LLDBDEBUGGER_WRN_UNKNOWN_EVENT), event.GetBroadcasterClass()));
670 m_pLog->WriteLog(msg);
674 m_pLog->WriteLog(CMICmnLLDBDebuggerHandleEvents::Instance().GetErrorDescription());
679 // Set the application to shutdown
680 m_pClientDriver->SetExitApplicationFlag(true);
689 //++ ------------------------------------------------------------------------------------
690 // Details: The main worker method for this thread.
692 // Args: vrbIsAlive - (W) True = *this thread is working, false = thread has exited.
693 // Return: MIstatus::success - Functional succeeded.
694 // MIstatus::failure - Functional failed.
698 CMICmnLLDBDebugger::ThreadRun(bool &vrbIsAlive)
700 return MonitorSBListenerEvents(vrbIsAlive);
703 //++ ------------------------------------------------------------------------------------
704 // Details: Let this thread clean up after itself.
707 // Return: MIstatus::success - Functionality succeeded.
708 // MIstatus::failure - Functionality failed.
712 CMICmnLLDBDebugger::ThreadFinish(void)
714 return MIstatus::success;
717 //++ ------------------------------------------------------------------------------------
718 // Details: Retrieve *this thread object's name.
721 // Return: CMIUtilString & - Text.
724 const CMIUtilString &
725 CMICmnLLDBDebugger::ThreadGetName(void) const
727 return m_constStrThisThreadId;