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.
70 bool CMICmnLLDBDebugger::Initialize( void )
72 m_clientUsageRefCnt++;
75 return MIstatus::success;
77 bool bOk = MIstatus::success;
79 ClrErrorDescription();
81 if( m_pClientDriver == nullptr )
84 errMsg = MIRSRC( IDS_LLDBDEBUGGER_ERR_CLIENTDRIVER );
87 // Note initialization order is important here as some resources depend on previous
88 MI::ModuleInit< CMICmnLog > ( IDS_MI_INIT_ERR_LOG , bOk, errMsg );
89 MI::ModuleInit< CMICmnResources > ( IDS_MI_INIT_ERR_RESOURCES , bOk, errMsg );
90 MI::ModuleInit< CMICmnThreadMgrStd > ( IDS_MI_INIT_ERR_THREADMGR , bOk, errMsg );
91 MI::ModuleInit< CMICmnLLDBDebuggerHandleEvents >( IDS_MI_INIT_ERR_OUTOFBANDHANDLER, bOk, errMsg );
92 MI::ModuleInit< CMICmnLLDBDebugSessionInfo > ( IDS_MI_INIT_ERR_DEBUGSESSIONINFO, bOk, errMsg );
94 // Note order is important here!
96 lldb::SBDebugger::Initialize();
97 if( bOk && !InitSBDebugger() )
100 if( !errMsg.empty() ) errMsg += ", ";
101 errMsg += GetErrorDescription().c_str();
103 if( bOk && !InitSBListener() )
106 if( !errMsg.empty() ) errMsg += ", ";
107 errMsg += GetErrorDescription().c_str();
109 bOk = bOk && InitStdStreams();
111 m_bInitialized = bOk;
113 if( !bOk && !HaveErrorDescription() )
115 CMIUtilString strInitError( CMIUtilString::Format( MIRSRC( IDS_MI_INIT_ERR_LLDBDEBUGGER ), errMsg.c_str() ) );
116 SetErrorDescription( strInitError );
122 //++ ------------------------------------------------------------------------------------
123 // Details: Release resources for *this debugger object.
126 // Return: MIstatus::success - Functionality succeeded.
127 // MIstatus::failure - Functionality failed.
130 bool CMICmnLLDBDebugger::Shutdown( void )
132 if( --m_clientUsageRefCnt > 0 )
133 return MIstatus::success;
135 if( !m_bInitialized )
136 return MIstatus::success;
138 m_bInitialized = false;
140 ClrErrorDescription();
142 bool bOk = MIstatus::success;
143 CMIUtilString errMsg;
145 // Explicitly delete the remote target in case MI needs to exit prematurely otherwise
146 // LLDB debugger may hang in its Destroy() fn waiting on events
147 m_lldbDebugger.DeleteTarget( CMICmnLLDBDebugSessionInfo::Instance().m_lldbTarget );
149 // Debug: May need this but does seem to work without it so commented out the fudge 19/06/2014
150 // It appears we need to wait as hang does not occur when hitting a debug breakpoint here
151 //const std::chrono::milliseconds time( 1000 );
152 //std::this_thread::sleep_for( time );
154 lldb::SBDebugger::Destroy( m_lldbDebugger );
155 lldb::SBDebugger::Terminate();
156 m_pClientDriver = nullptr;
157 m_mapBroadcastClassNameToEventMask.clear();
158 m_mapIdToEventMask.clear();
160 // Note shutdown order is important here
161 MI::ModuleShutdown< CMICmnLLDBDebugSessionInfo > ( IDS_MI_INIT_ERR_DEBUGSESSIONINFO, bOk, errMsg );
162 MI::ModuleShutdown< CMICmnLLDBDebuggerHandleEvents >( IDS_MI_INIT_ERR_OUTOFBANDHANDLER, bOk, errMsg );
163 MI::ModuleShutdown< CMICmnThreadMgrStd > ( IDS_MI_INIT_ERR_THREADMGR , bOk, errMsg );
164 MI::ModuleShutdown< CMICmnResources > ( IDS_MI_INIT_ERR_RESOURCES , bOk, errMsg );
165 MI::ModuleShutdown< CMICmnLog > ( IDS_MI_INIT_ERR_LOG , bOk, errMsg );
169 SetErrorDescriptionn( MIRSRC( IDS_MI_SHTDWN_ERR_LLDBDEBUGGER ), errMsg.c_str() );
172 return MIstatus::success;
175 //++ ------------------------------------------------------------------------------------
176 // Details: Return the LLDB debugger instance created for this debug session.
179 // Return: lldb::SBDebugger & - LLDB debugger object reference.
182 lldb::SBDebugger & CMICmnLLDBDebugger::GetTheDebugger( void )
184 return m_lldbDebugger;
187 //++ ------------------------------------------------------------------------------------
188 // Details: Return the LLDB listener instance created for this debug session.
191 // Return: lldb::SBListener & - LLDB listener object reference.
194 lldb::SBListener & CMICmnLLDBDebugger::GetTheListener( void )
196 return m_lldbListener;
199 //++ ------------------------------------------------------------------------------------
200 // Details: Set the client driver that wants to use *this LLDB debugger. Call this function
201 // prior to Initialize().
203 // Args: vClientDriver - (R) A driver.
204 // Return: MIstatus::success - Functionality succeeded.
205 // MIstatus::failure - Functionality failed.
208 bool CMICmnLLDBDebugger::SetDriver( const CMIDriverBase & vClientDriver )
210 m_pClientDriver = const_cast< CMIDriverBase * >( &vClientDriver );
212 return MIstatus::success;
215 //++ ------------------------------------------------------------------------------------
216 // Details: Get the client driver that is use *this LLDB debugger.
218 // Args: vClientDriver - (R) A driver.
219 // Return: CMIDriverBase & - A driver instance.
222 CMIDriverBase & CMICmnLLDBDebugger::GetDriver( void ) const
224 return *m_pClientDriver;
227 //++ ------------------------------------------------------------------------------------
228 // Details: Initialize the LLDB Debugger object.
231 // Return: MIstatus::success - Functionality succeeded.
232 // MIstatus::failure - Functionality failed.
235 bool CMICmnLLDBDebugger::InitSBDebugger( void )
237 m_lldbDebugger = lldb::SBDebugger::Create( false );
238 if( m_lldbDebugger.IsValid() )
239 return MIstatus::success;
241 SetErrorDescription( MIRSRC( IDS_LLDBDEBUGGER_ERR_INVALIDDEBUGGER ) );
242 return MIstatus::failure;
245 //++ ------------------------------------------------------------------------------------
246 // Details: Set the LLDB Debugger's std in, err and out streams. (Not implemented left
247 // here for reference. Was called in the CMICmnLLDBDebugger::Initialize() )
250 // Return: MIstatus::success - Functionality succeeded.
251 // MIstatus::failure - Functionality failed.
254 bool CMICmnLLDBDebugger::InitStdStreams( void )
256 // This is not required when operating the MI driver's code as it has its own
257 // streams. Setting the Stdin for the lldbDebugger especially on LINUX will cause
258 // another thread to run and partially consume stdin data meant for MI stdin handler
259 //m_lldbDebugger.SetErrorFileHandle( m_pClientDriver->GetStderr(), false );
260 //m_lldbDebugger.SetOutputFileHandle( m_pClientDriver->GetStdout(), false );
261 //m_lldbDebugger.SetInputFileHandle( m_pClientDriver->GetStdin(), false );
263 return MIstatus::success;
266 //++ ------------------------------------------------------------------------------------
267 // Details: Set up the events from the SBDebugger's we would to listent to.
270 // Return: MIstatus::success - Functionality succeeded.
271 // MIstatus::failure - Functionality failed.
274 bool CMICmnLLDBDebugger::InitSBListener( void )
276 m_lldbListener = m_lldbDebugger.GetListener();
277 if( !m_lldbListener.IsValid() )
279 SetErrorDescription( MIRSRC( IDS_LLDBDEBUGGER_ERR_INVALIDLISTENER ) );
280 return MIstatus::failure;
283 const CMIUtilString strDbgId( "CMICmnLLDBDebugger1" );
284 MIuint eventMask = lldb::SBTarget::eBroadcastBitBreakpointChanged;
285 bool bOk = RegisterForEvent( strDbgId, CMIUtilString( lldb::SBTarget::GetBroadcasterClassName() ), eventMask );
287 eventMask = lldb::SBThread::eBroadcastBitStackChanged;
288 bOk = bOk && RegisterForEvent( strDbgId, CMIUtilString( lldb::SBThread::GetBroadcasterClassName() ), eventMask );
290 eventMask = lldb::SBProcess::eBroadcastBitStateChanged |
291 lldb::SBProcess::eBroadcastBitInterrupt |
292 lldb::SBProcess::eBroadcastBitSTDOUT |
293 lldb::SBProcess::eBroadcastBitSTDERR |
294 lldb::SBProcess::eBroadcastBitProfileData;
295 bOk = bOk && RegisterForEvent( strDbgId, CMIUtilString( lldb::SBProcess::GetBroadcasterClassName() ), eventMask );
297 eventMask = lldb::SBCommandInterpreter::eBroadcastBitQuitCommandReceived |
298 lldb::SBCommandInterpreter::eBroadcastBitThreadShouldExit |
299 lldb::SBCommandInterpreter::eBroadcastBitAsynchronousOutputData |
300 lldb::SBCommandInterpreter::eBroadcastBitAsynchronousErrorData;
301 bOk = bOk && RegisterForEvent( strDbgId, CMIUtilString( lldb::SBCommandInterpreter::GetBroadcasterClass() ), eventMask );
306 //++ ------------------------------------------------------------------------------------
307 // Details: Register with the debugger, the SBListener, the type of events you are interested
308 // in. Others, like commands, may have already set the mask.
310 // Args: vClientName - (R) ID of the client who wants these events set.
311 // vBroadcasterClass - (R) The SBBroadcaster's class name.
312 // vEventMask - (R) The mask of events to listen for.
313 // Return: MIstatus::success - Functionality succeeded.
314 // MIstatus::failure - Functionality failed.
317 bool CMICmnLLDBDebugger::RegisterForEvent( const CMIUtilString & vClientName, const CMIUtilString & vBroadcasterClass, const MIuint vEventMask )
319 MIuint existingMask = 0;
320 if( !BroadcasterGetMask( vBroadcasterClass, existingMask ) )
321 return MIstatus::failure;
323 if( !ClientSaveMask( vClientName, vBroadcasterClass, vEventMask ) )
324 return MIstatus::failure;
326 const MIchar * pBroadCasterName = vBroadcasterClass.c_str();
327 MIuint eventMask = vEventMask;
328 eventMask += existingMask;
329 const MIuint result = m_lldbListener.StartListeningForEventClass( m_lldbDebugger, pBroadCasterName, eventMask );
332 SetErrorDescription( CMIUtilString::Format( MIRSRC( IDS_LLDBDEBUGGER_ERR_STARTLISTENER ), pBroadCasterName ) );
333 return MIstatus::failure;
336 return BroadcasterSaveMask( vBroadcasterClass, eventMask );
339 //++ ------------------------------------------------------------------------------------
340 // Details: Register with the debugger, the SBListener, the type of events you are interested
341 // in. Others, like commands, may have already set the mask.
343 // Args: vClientName - (R) ID of the client who wants these events set.
344 // vBroadcaster - (R) An SBBroadcaster's derived class.
345 // vEventMask - (R) The mask of events to listen for.
346 // Return: MIstatus::success - Functionality succeeded.
347 // MIstatus::failure - Functionality failed.
350 bool CMICmnLLDBDebugger::RegisterForEvent( const CMIUtilString & vClientName, const lldb::SBBroadcaster & vBroadcaster, const MIuint vEventMask )
352 const MIchar * pBroadcasterName = vBroadcaster.GetName();
353 if( pBroadcasterName == nullptr )
355 SetErrorDescription( CMIUtilString::Format( MIRSRC( IDS_LLDBDEBUGGER_ERR_BROARDCASTER_NAME ), MIRSRC( IDS_WORD_INVALIDNULLPTR ) ) );
356 return MIstatus::failure;
358 CMIUtilString broadcasterName( pBroadcasterName );
359 if( broadcasterName.length() == 0 )
361 SetErrorDescription( CMIUtilString::Format( MIRSRC( IDS_LLDBDEBUGGER_ERR_BROARDCASTER_NAME ), MIRSRC( IDS_WORD_INVALIDEMPTY ) ) );
362 return MIstatus::failure;
365 MIuint existingMask = 0;
366 if( !BroadcasterGetMask( broadcasterName, existingMask ) )
367 return MIstatus::failure;
369 if( !ClientSaveMask( vClientName, broadcasterName, vEventMask ) )
370 return MIstatus::failure;
372 MIuint eventMask = vEventMask;
373 eventMask += existingMask;
374 const MIuint result = m_lldbListener.StartListeningForEvents( vBroadcaster, eventMask );
377 SetErrorDescription( CMIUtilString::Format( MIRSRC( IDS_LLDBDEBUGGER_ERR_STARTLISTENER ), pBroadcasterName ) );
378 return MIstatus::failure;
381 return BroadcasterSaveMask( broadcasterName, eventMask );
384 //++ ------------------------------------------------------------------------------------
385 // Details: Unregister with the debugger, the SBListener, the type of events you are no
386 // longer interested in. Others, like commands, may still remain interested so
387 // an event may not necessarily be stopped.
389 // Args: vClientName - (R) ID of the client who no longer requires these events.
390 // vBroadcasterClass - (R) The SBBroadcaster's class name.
391 // Return: MIstatus::success - Functionality succeeded.
392 // MIstatus::failure - Functionality failed.
395 bool CMICmnLLDBDebugger::UnregisterForEvent( const CMIUtilString & vClientName, const CMIUtilString & vBroadcasterClass )
397 MIuint clientsEventMask = 0;
398 if( !ClientGetTheirMask( vClientName, vBroadcasterClass, clientsEventMask ) )
399 return MIstatus::failure;
400 if( !ClientRemoveTheirMask( vClientName, vBroadcasterClass ) )
401 return MIstatus::failure;
403 const MIuint otherClientsEventMask = ClientGetMaskForAllClients( vBroadcasterClass );
404 MIuint newEventMask = 0;
405 for( MIuint i = 0; i < 32; i++ )
407 const MIuint bit = 1 << i;
408 const MIuint clientBit = bit & clientsEventMask;
409 const MIuint othersBit = bit & otherClientsEventMask;
410 if( (clientBit != 0) && (othersBit == 0) )
412 newEventMask += clientBit;
416 const MIchar * pBroadCasterName = vBroadcasterClass.c_str();
417 if( !m_lldbListener.StopListeningForEventClass( m_lldbDebugger, pBroadCasterName, newEventMask ) )
419 SetErrorDescription( CMIUtilString::Format( MIRSRC( IDS_LLDBDEBUGGER_ERR_STOPLISTENER ), vClientName.c_str(), pBroadCasterName ) );
420 return MIstatus::failure;
423 return BroadcasterSaveMask( vBroadcasterClass, otherClientsEventMask );
426 //++ ------------------------------------------------------------------------------------
427 // Details: Given the SBBroadcaster class name retrieve it's current event mask.
429 // Args: vBroadcasterClass - (R) The SBBroadcaster's class name.
430 // vEventMask - (W) The mask of events to listen for.
431 // Return: MIstatus::success - Functionality succeeded.
432 // MIstatus::failure - Functionality failed.
435 bool CMICmnLLDBDebugger::BroadcasterGetMask( const CMIUtilString & vBroadcasterClass, MIuint & vwEventMask ) const
439 if( vBroadcasterClass.empty() )
441 SetErrorDescription( CMIUtilString::Format( MIRSRC( IDS_LLDBDEBUGGER_ERR_INVALIDBROADCASTER ), vBroadcasterClass.c_str() ) );
442 return MIstatus::failure;
445 const MapBroadcastClassNameToEventMask_t::const_iterator it = m_mapBroadcastClassNameToEventMask.find( vBroadcasterClass );
446 if( it != m_mapBroadcastClassNameToEventMask.end() )
448 vwEventMask = (*it).second;
451 return MIstatus::success;
454 //++ ------------------------------------------------------------------------------------
455 // Details: Remove the event mask for the specified SBBroadcaster class name.
457 // Args: vBroadcasterClass - (R) The SBBroadcaster's class name.
458 // Return: MIstatus::success - Functionality succeeded.
459 // MIstatus::failure - Functionality failed.
462 bool CMICmnLLDBDebugger::BroadcasterRemoveMask( const CMIUtilString & vBroadcasterClass )
464 MapBroadcastClassNameToEventMask_t::const_iterator it = m_mapBroadcastClassNameToEventMask.find( vBroadcasterClass );
465 if( it != m_mapBroadcastClassNameToEventMask.end() )
467 m_mapBroadcastClassNameToEventMask.erase( it );
470 return MIstatus::success;
473 //++ ------------------------------------------------------------------------------------
474 // Details: Given the SBBroadcaster class name save it's current event mask.
476 // Args: vBroadcasterClass - (R) The SBBroadcaster's class name.
477 // vEventMask - (R) The mask of events to listen for.
478 // Return: MIstatus::success - Functionality succeeded.
479 // MIstatus::failure - Functionality failed.
482 bool CMICmnLLDBDebugger::BroadcasterSaveMask( const CMIUtilString & vBroadcasterClass, const MIuint vEventMask )
484 if( vBroadcasterClass.empty() )
486 SetErrorDescription( CMIUtilString::Format( MIRSRC( IDS_LLDBDEBUGGER_ERR_INVALIDBROADCASTER ), vBroadcasterClass.c_str() ) );
487 return MIstatus::failure;
490 BroadcasterRemoveMask( vBroadcasterClass );
491 MapPairBroadcastClassNameToEventMask_t pr( vBroadcasterClass, vEventMask );
492 m_mapBroadcastClassNameToEventMask.insert( pr );
494 return MIstatus::success;
497 //++ ------------------------------------------------------------------------------------
498 // Details: Iterate all the clients who have registered event masks against particular
499 // SBBroadcasters and build up the mask that is for all of them.
501 // Args: vBroadcasterClass - (R) The broadcaster to retrieve the mask for.
502 // Return: MIuint - Event mask.
505 MIuint CMICmnLLDBDebugger::ClientGetMaskForAllClients( const CMIUtilString & vBroadcasterClass ) const
508 MapIdToEventMask_t::const_iterator it = m_mapIdToEventMask.begin();
509 while( it != m_mapIdToEventMask.end() )
511 const CMIUtilString & rId( (*it).first );
512 if( rId.find( vBroadcasterClass.c_str() ) != std::string::npos )
514 const MIuint clientsMask = (*it).second;
525 //++ ------------------------------------------------------------------------------------
526 // Details: Given the client save its particular event requirements.
528 // Args: vClientName - (R) The Client's unique ID.
529 // vBroadcasterClass - (R) The SBBroadcaster's class name targeted for the events.
530 // vEventMask - (R) The mask of events to listen for.
531 // Return: MIstatus::success - Functionality succeeded.
532 // MIstatus::failure - Functionality failed.
535 bool CMICmnLLDBDebugger::ClientSaveMask( const CMIUtilString & vClientName, const CMIUtilString & vBroadcasterClass, const MIuint vEventMask )
537 if( vClientName.empty() )
539 SetErrorDescription( CMIUtilString::Format( MIRSRC( IDS_LLDBDEBUGGER_ERR_INVALIDCLIENTNAME ), vClientName.c_str() ) );
540 return MIstatus::failure;
543 CMIUtilString strId( vBroadcasterClass );
544 strId += vClientName;
546 ClientRemoveTheirMask( vClientName, vBroadcasterClass );
547 MapPairIdToEventMask_t pr( strId, vEventMask );
548 m_mapIdToEventMask.insert( pr );
550 return MIstatus::success;
553 //++ ------------------------------------------------------------------------------------
554 // Details: Given the client remove it's particular event requirements.
556 // Args: vClientName - (R) The Client's unique ID.
557 // vBroadcasterClass - (R) The SBBroadcaster's class name.
558 // Return: MIstatus::success - Functionality succeeded.
559 // MIstatus::failure - Functionality failed.
562 bool CMICmnLLDBDebugger::ClientRemoveTheirMask( const CMIUtilString & vClientName, const CMIUtilString & vBroadcasterClass )
564 if( vClientName.empty() )
566 SetErrorDescription( CMIUtilString::Format( MIRSRC( IDS_LLDBDEBUGGER_ERR_INVALIDCLIENTNAME ), vClientName.c_str() ) );
567 return MIstatus::failure;
570 CMIUtilString strId( vBroadcasterClass );
571 strId += vClientName;
573 const MapIdToEventMask_t::const_iterator it = m_mapIdToEventMask.find( strId );
574 if( it != m_mapIdToEventMask.end() )
576 m_mapIdToEventMask.erase( it );
579 return MIstatus::success;
582 //++ ------------------------------------------------------------------------------------
583 // Details: Retrieve the client's event mask used for on a particular SBBroadcaster.
585 // Args: vClientName - (R) The Client's unique ID.
586 // vBroadcasterClass - (R) The SBBroadcaster's class name.
587 // vwEventMask - (W) The client's mask.
588 // Return: MIstatus::success - Functionality succeeded.
589 // MIstatus::failure - Functionality failed.
592 bool CMICmnLLDBDebugger::ClientGetTheirMask( const CMIUtilString & vClientName, const CMIUtilString & vBroadcasterClass, MIuint & vwEventMask )
596 if( vClientName.empty() )
598 SetErrorDescription( CMIUtilString::Format( MIRSRC( IDS_LLDBDEBUGGER_ERR_INVALIDCLIENTNAME ), vClientName.c_str() ) );
599 return MIstatus::failure;
602 CMIUtilString strId( vBroadcasterClass.c_str() );
603 strId += vClientName;
605 const MapIdToEventMask_t::const_iterator it = m_mapIdToEventMask.find( strId );
606 if( it != m_mapIdToEventMask.end() )
608 vwEventMask = (*it).second;
611 SetErrorDescription( CMIUtilString::Format( MIRSRC( IDS_LLDBDEBUGGER_ERR_CLIENTNOTREGISTERD ), vClientName.c_str() ) );
613 return MIstatus::failure;
616 //++ ------------------------------------------------------------------------------------
617 // Details: Momentarily wait for an events being broadcast and inspect those that do
618 // come this way. Check if the target should exit event if so start shutting
619 // down this thread and the application. Any other events pass on to the
620 // Out-of-band handler to futher determine what kind of event arrived.
621 // This function runs in the thread "MI debugger event".
623 // Args: vrbIsAlive - (W) False = yes exit event monitoring thread, true = continue.
624 // Return: MIstatus::success - Functional succeeded.
625 // MIstatus::failure - Functional failed.
628 bool CMICmnLLDBDebugger::MonitorSBListenerEvents( bool & vrbIsAlive )
633 const bool bGotEvent = m_lldbListener.GetNextEvent( event );
634 if ( !bGotEvent || !event.IsValid() )
636 const std::chrono::milliseconds time( 1 );
637 std::this_thread::sleep_for( time );
638 return MIstatus::success;
640 if( !event.GetBroadcaster().IsValid() )
641 return MIstatus::success;
644 m_pLog->WriteLog( CMIUtilString::Format( "##### An event occurred: %s", event.GetBroadcasterClass() ) );
646 bool bHandledEvent = false;
647 bool bExitAppEvent = false;
648 const bool bOk = CMICmnLLDBDebuggerHandleEvents::Instance().HandleEvent( event, bHandledEvent, bExitAppEvent );
651 const CMIUtilString msg( CMIUtilString::Format( MIRSRC( IDS_LLDBDEBUGGER_WRN_UNKNOWN_EVENT ), event.GetBroadcasterClass() ) );
652 m_pLog->WriteLog( msg );
656 m_pLog->WriteLog( CMICmnLLDBDebuggerHandleEvents::Instance().GetErrorDescription() );
661 // Set the application to shutdown
662 m_pClientDriver->SetExitApplicationFlag( true );
671 //++ ------------------------------------------------------------------------------------
672 // Details: The main worker method for this thread.
674 // Args: vrbIsAlive = (W) True = *this thread is working, false = thread has exited.
675 // Return: MIstatus::success - Functional succeeded.
676 // MIstatus::failure - Functional failed.
679 bool CMICmnLLDBDebugger::ThreadRun( bool & vrbIsAlive )
681 return MonitorSBListenerEvents( vrbIsAlive );
684 //++ ------------------------------------------------------------------------------------
685 // Details: Let this thread clean up after itself.
688 // Return: MIstatus::success - Functionality succeeded.
689 // MIstatus::failure - Functionality failed.
692 bool CMICmnLLDBDebugger::ThreadFinish( void )
694 return MIstatus::success;
697 //++ ------------------------------------------------------------------------------------
698 // Details: Retrieve *this thread object's name.
701 // Return: CMIUtilString & - Text.
704 const CMIUtilString & CMICmnLLDBDebugger::ThreadGetName( void ) const
706 return m_constStrThisThreadId;