diff options
Diffstat (limited to 'tools/lldb-mi/MICmnLLDBDebugger.cpp')
| -rw-r--r-- | tools/lldb-mi/MICmnLLDBDebugger.cpp | 905 | 
1 files changed, 0 insertions, 905 deletions
| diff --git a/tools/lldb-mi/MICmnLLDBDebugger.cpp b/tools/lldb-mi/MICmnLLDBDebugger.cpp deleted file mode 100644 index b22e7d9a1fe6..000000000000 --- a/tools/lldb-mi/MICmnLLDBDebugger.cpp +++ /dev/null @@ -1,905 +0,0 @@ -//===-- MICmnLLDBDebugger.cpp -----------------------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// Third party headers: -#include "lldb/API/SBCommandInterpreter.h" -#include "lldb/API/SBProcess.h" -#include "lldb/API/SBStream.h" -#include "lldb/API/SBTarget.h" -#include "lldb/API/SBThread.h" -#include "lldb/API/SBType.h" -#include "lldb/API/SBTypeCategory.h" -#include "lldb/API/SBTypeNameSpecifier.h" -#include "lldb/API/SBTypeSummary.h" -#include <cassert> - -// In-house headers: -#include "MICmnLLDBDebugSessionInfo.h" -#include "MICmnLLDBDebugger.h" -#include "MICmnLLDBDebuggerHandleEvents.h" -#include "MICmnLog.h" -#include "MICmnResources.h" -#include "MICmnThreadMgrStd.h" -#include "MIDriverBase.h" -#include "MIUtilSingletonHelper.h" - -//++ -// MI private summary providers -static inline bool MI_char_summary_provider(lldb::SBValue value, -                                            lldb::SBTypeSummaryOptions options, -                                            lldb::SBStream &stream) { -  if (!value.IsValid()) -    return false; - -  lldb::SBType value_type = value.GetType(); -  if (!value_type.IsValid()) -    return false; - -  lldb::BasicType type_code = value_type.GetBasicType(); -  if (type_code == lldb::eBasicTypeSignedChar) -    stream.Printf("%d %s", (int)value.GetValueAsSigned(), -                  CMIUtilString::WithNullAsEmpty(value.GetValue())); -  else if (type_code == lldb::eBasicTypeUnsignedChar) -    stream.Printf("%u %s", (unsigned)value.GetValueAsUnsigned(), -                  CMIUtilString::WithNullAsEmpty(value.GetValue())); -  else -    return false; - -  return true; -} - -//++ -// MI summary helper routines -static inline bool MI_add_summary(lldb::SBTypeCategory category, -                                  const char *typeName, -                                  lldb::SBTypeSummary::FormatCallback cb, -                                  uint32_t options, bool regex = false) { -#if defined(LLDB_DISABLE_PYTHON) -  return false; -#else -  lldb::SBTypeSummary summary = -      lldb::SBTypeSummary::CreateWithCallback(cb, options); -  return summary.IsValid() -             ? category.AddTypeSummary( -                   lldb::SBTypeNameSpecifier(typeName, regex), summary) -             : false; -#endif -} - -//++ -// Details: CMICmnLLDBDebugger constructor. -// Type:    Method. -// Args:    None. -// Return:  None. -// Throws:  None. -//-- -CMICmnLLDBDebugger::CMICmnLLDBDebugger() -    : m_constStrThisThreadId("MI debugger event") {} - -//++ -// Details: CMICmnLLDBDebugger destructor. -// Type:    Overridable. -// Args:    None. -// Return:  None. -// Throws:  None. -//-- -CMICmnLLDBDebugger::~CMICmnLLDBDebugger() { Shutdown(); } - -//++ -// Details: Initialize resources for *this debugger object. -// Type:    Method. -// Args:    None. -// Return:  MIstatus::success - Functionality succeeded. -//          MIstatus::failure - Functionality failed. -// Throws:  None. -//-- -bool CMICmnLLDBDebugger::Initialize() { -  m_clientUsageRefCnt++; - -  if (m_bInitialized) -    return MIstatus::success; - -  bool bOk = MIstatus::success; -  CMIUtilString errMsg; -  ClrErrorDescription(); - -  if (m_pClientDriver == nullptr) { -    bOk = false; -    errMsg = MIRSRC(IDS_LLDBDEBUGGER_ERR_CLIENTDRIVER); -  } - -  // Note initialization order is important here as some resources depend on -  // previous -  MI::ModuleInit<CMICmnLog>(IDS_MI_INIT_ERR_LOG, bOk, errMsg); -  MI::ModuleInit<CMICmnResources>(IDS_MI_INIT_ERR_RESOURCES, bOk, errMsg); -  MI::ModuleInit<CMICmnThreadMgrStd>(IDS_MI_INIT_ERR_THREADMGR, bOk, errMsg); -  MI::ModuleInit<CMICmnLLDBDebuggerHandleEvents>( -      IDS_MI_INIT_ERR_OUTOFBANDHANDLER, bOk, errMsg); -  MI::ModuleInit<CMICmnLLDBDebugSessionInfo>(IDS_MI_INIT_ERR_DEBUGSESSIONINFO, -                                             bOk, errMsg); - -  // Note order is important here! -  if (bOk) -    lldb::SBDebugger::Initialize(); -  if (bOk && !InitSBDebugger()) { -    bOk = false; -    if (!errMsg.empty()) -      errMsg += ", "; -    errMsg += GetErrorDescription().c_str(); -  } -  if (bOk && !InitSBListener()) { -    bOk = false; -    if (!errMsg.empty()) -      errMsg += ", "; -    errMsg += GetErrorDescription().c_str(); -  } -  bOk = bOk && InitStdStreams(); -  bOk = bOk && RegisterMISummaryProviders(); -  m_bInitialized = bOk; - -  if (!bOk && !HaveErrorDescription()) { -    CMIUtilString strInitError(CMIUtilString::Format( -        MIRSRC(IDS_MI_INIT_ERR_LLDBDEBUGGER), errMsg.c_str())); -    SetErrorDescription(strInitError); -  } - -  return bOk; -} - -//++ -// Details: Release resources for *this debugger object. -// Type:    Method. -// Args:    None. -// Return:  MIstatus::success - Functionality succeeded. -//          MIstatus::failure - Functionality failed. -// Throws:  None. -//-- -bool CMICmnLLDBDebugger::Shutdown() { -  if (--m_clientUsageRefCnt > 0) -    return MIstatus::success; - -  if (!m_bInitialized) -    return MIstatus::success; - -  m_bInitialized = false; - -  ClrErrorDescription(); - -  bool bOk = MIstatus::success; -  CMIUtilString errMsg; - -  // Explicitly delete the remote target in case MI needs to exit prematurely -  // otherwise -  // LLDB debugger may hang in its Destroy() fn waiting on events -  lldb::SBTarget sbTarget = CMICmnLLDBDebugSessionInfo::Instance().GetTarget(); -  m_lldbDebugger.DeleteTarget(sbTarget); - -  // Debug: May need this but does seem to work without it so commented out the -  // fudge 19/06/2014 -  // It appears we need to wait as hang does not occur when hitting a debug -  // breakpoint here -  // const std::chrono::milliseconds time( 1000 ); -  // std::this_thread::sleep_for( time ); - -  lldb::SBDebugger::Destroy(m_lldbDebugger); -  lldb::SBDebugger::Terminate(); -  m_pClientDriver = nullptr; -  m_mapBroadcastClassNameToEventMask.clear(); -  m_mapIdToEventMask.clear(); - -  // Note shutdown order is important here -  MI::ModuleShutdown<CMICmnLLDBDebugSessionInfo>( -      IDS_MI_INIT_ERR_DEBUGSESSIONINFO, bOk, errMsg); -  MI::ModuleShutdown<CMICmnLLDBDebuggerHandleEvents>( -      IDS_MI_INIT_ERR_OUTOFBANDHANDLER, bOk, errMsg); -  MI::ModuleShutdown<CMICmnThreadMgrStd>(IDS_MI_INIT_ERR_THREADMGR, bOk, -                                         errMsg); -  MI::ModuleShutdown<CMICmnResources>(IDS_MI_INIT_ERR_RESOURCES, bOk, errMsg); -  MI::ModuleShutdown<CMICmnLog>(IDS_MI_INIT_ERR_LOG, bOk, errMsg); - -  if (!bOk) { -    SetErrorDescriptionn(MIRSRC(IDS_MI_SHTDWN_ERR_LLDBDEBUGGER), -                         errMsg.c_str()); -  } - -  return MIstatus::success; -} - -//++ -// Details: Return the LLDB debugger instance created for this debug session. -// Type:    Method. -// Args:    None. -// Return:  lldb::SBDebugger & - LLDB debugger object reference. -// Throws:  None. -//-- -lldb::SBDebugger &CMICmnLLDBDebugger::GetTheDebugger() { -  return m_lldbDebugger; -} - -//++ -// Details: Return the LLDB listener instance created for this debug session. -// Type:    Method. -// Args:    None. -// Return:  lldb::SBListener & - LLDB listener object reference. -// Throws:  None. -//-- -lldb::SBListener &CMICmnLLDBDebugger::GetTheListener() { -  return m_lldbListener; -} - -//++ -// Details: Set the client driver that wants to use *this LLDB debugger. Call -// this function -//          prior to Initialize(). -// Type:    Method. -// Args:    vClientDriver   - (R) A driver. -// Return:  MIstatus::success - Functionality succeeded. -//          MIstatus::failure - Functionality failed. -// Throws:  None. -//-- -bool CMICmnLLDBDebugger::SetDriver(const CMIDriverBase &vClientDriver) { -  m_pClientDriver = const_cast<CMIDriverBase *>(&vClientDriver); - -  return MIstatus::success; -} - -//++ -// Details: Get the client driver that is use *this LLDB debugger. -// Type:    Method. -// Args:    vClientDriver   - (R) A driver. -// Return:  CMIDriverBase & - A driver instance. -// Throws:  None. -//-- -CMIDriverBase &CMICmnLLDBDebugger::GetDriver() const { -  return *m_pClientDriver; -} - -//++ -// Details: Wait until all events have been handled. -//          This function works in pair with -//          CMICmnLLDBDebugger::MonitorSBListenerEvents -//          that handles events from queue. When all events were handled and -//          queue is -//          empty the MonitorSBListenerEvents notifies this function that it's -//          ready to -//          go on. To synchronize them the m_mutexEventQueue and -//          m_conditionEventQueueEmpty are used. -// Type:    Method. -// Args:    None. -// Return:  None. -// Throws:  None. -//-- -void CMICmnLLDBDebugger::WaitForHandleEvent() { -  std::unique_lock<std::mutex> lock(m_mutexEventQueue); - -  lldb::SBEvent event; -  if (ThreadIsActive() && m_lldbListener.PeekAtNextEvent(event)) -    m_conditionEventQueueEmpty.wait(lock); -} - -//++ -// Details: Check if need to rebroadcast stop event. This function will return -// true if -//          debugger is in synchronouse mode. In such case the -//          CMICmnLLDBDebugger::RebroadcastStopEvent should be called to -//          rebroadcast -//          a new stop event (if any). -// Type:    Method. -// Args:    None. -// Return:  bool    - True = Need to rebroadcast stop event, false = otherwise. -// Throws:  None. -//-- -bool CMICmnLLDBDebugger::CheckIfNeedToRebroadcastStopEvent() { -  CMICmnLLDBDebugSessionInfo &rSessionInfo( -      CMICmnLLDBDebugSessionInfo::Instance()); -  if (!rSessionInfo.GetDebugger().GetAsync()) { -    const bool include_expression_stops = false; -    m_nLastStopId = -        CMICmnLLDBDebugSessionInfo::Instance().GetProcess().GetStopID( -            include_expression_stops); -    return true; -  } - -  return false; -} - -//++ -// Details: Rebroadcast stop event if needed. This function should be called -// only if the -//          CMICmnLLDBDebugger::CheckIfNeedToRebroadcastStopEvent() returned -//          true. -// Type:    Method. -// Args:    None. -// Return:  None. -// Throws:  None. -//-- -void CMICmnLLDBDebugger::RebroadcastStopEvent() { -  lldb::SBProcess process = CMICmnLLDBDebugSessionInfo::Instance().GetProcess(); -  const bool include_expression_stops = false; -  const uint32_t nStopId = process.GetStopID(include_expression_stops); -  if (m_nLastStopId != nStopId) { -    lldb::SBEvent event = process.GetStopEventForStopID(nStopId); -    process.GetBroadcaster().BroadcastEvent(event); -  } -} - -//++ -// Details: Initialize the LLDB Debugger object. -// Type:    Method. -// Args:    None. -// Return:  MIstatus::success - Functionality succeeded. -//          MIstatus::failure - Functionality failed. -// Throws:  None. -//-- -bool CMICmnLLDBDebugger::InitSBDebugger() { -  m_lldbDebugger = lldb::SBDebugger::Create(false); -  if (!m_lldbDebugger.IsValid()) { -    SetErrorDescription(MIRSRC(IDS_LLDBDEBUGGER_ERR_INVALIDDEBUGGER)); -    return MIstatus::failure; -  } - -  m_lldbDebugger.GetCommandInterpreter().SetPromptOnQuit(false); - -  return MIstatus::success; -} - -//++ -// Details: Set the LLDB Debugger's std in, err and out streams. (Not -// implemented left -//          here for reference. Was called in the -//          CMICmnLLDBDebugger::Initialize() ) -// Type:    Method. -// Args:    None. -// Return:  MIstatus::success - Functionality succeeded. -//          MIstatus::failure - Functionality failed. -// Throws:  None. -//-- -bool CMICmnLLDBDebugger::InitStdStreams() { -  // This is not required when operating the MI driver's code as it has its own -  // streams. Setting the Stdin for the lldbDebugger especially on LINUX will -  // cause -  // another thread to run and partially consume stdin data meant for MI stdin -  // handler -  // m_lldbDebugger.SetErrorFileHandle( m_pClientDriver->GetStderr(), false ); -  // m_lldbDebugger.SetOutputFileHandle( m_pClientDriver->GetStdout(), false ); -  // m_lldbDebugger.SetInputFileHandle( m_pClientDriver->GetStdin(), false ); - -  return MIstatus::success; -} - -//++ -// Details: Set up the events from the SBDebugger's we would like to listen to. -// Type:    Method. -// Args:    None. -// Return:  MIstatus::success - Functionality succeeded. -//          MIstatus::failure - Functionality failed. -// Throws:  None. -//-- -bool CMICmnLLDBDebugger::InitSBListener() { -  m_lldbListener = m_lldbDebugger.GetListener(); -  if (!m_lldbListener.IsValid()) { -    SetErrorDescription(MIRSRC(IDS_LLDBDEBUGGER_ERR_INVALIDLISTENER)); -    return MIstatus::failure; -  } - -  const CMIUtilString strDbgId("CMICmnLLDBDebugger1"); -  MIuint eventMask = lldb::SBTarget::eBroadcastBitBreakpointChanged | -                     lldb::SBTarget::eBroadcastBitModulesLoaded | -                     lldb::SBTarget::eBroadcastBitModulesUnloaded | -                     lldb::SBTarget::eBroadcastBitWatchpointChanged | -                     lldb::SBTarget::eBroadcastBitSymbolsLoaded; -  bool bOk = RegisterForEvent( -      strDbgId, CMIUtilString(lldb::SBTarget::GetBroadcasterClassName()), -      eventMask); - -  eventMask = lldb::SBThread::eBroadcastBitStackChanged; -  bOk = bOk && -        RegisterForEvent( -            strDbgId, CMIUtilString(lldb::SBThread::GetBroadcasterClassName()), -            eventMask); - -  eventMask = lldb::SBProcess::eBroadcastBitStateChanged | -              lldb::SBProcess::eBroadcastBitInterrupt | -              lldb::SBProcess::eBroadcastBitSTDOUT | -              lldb::SBProcess::eBroadcastBitSTDERR | -              lldb::SBProcess::eBroadcastBitProfileData | -              lldb::SBProcess::eBroadcastBitStructuredData; -  bOk = bOk && -        RegisterForEvent( -            strDbgId, CMIUtilString(lldb::SBProcess::GetBroadcasterClassName()), -            eventMask); - -  eventMask = lldb::SBCommandInterpreter::eBroadcastBitQuitCommandReceived | -              lldb::SBCommandInterpreter::eBroadcastBitThreadShouldExit | -              lldb::SBCommandInterpreter::eBroadcastBitAsynchronousOutputData | -              lldb::SBCommandInterpreter::eBroadcastBitAsynchronousErrorData; -  bOk = bOk && -        RegisterForEvent( -            strDbgId, m_lldbDebugger.GetCommandInterpreter().GetBroadcaster(), -            eventMask); - -  return bOk; -} - -//++ -// Details: Register with the debugger, the SBListener, the type of events you -// are interested -//          in. Others, like commands, may have already set the mask. -// Type:    Method. -// Args:    vClientName         - (R) ID of the client who wants these events -// set. -//          vBroadcasterClass   - (R) The SBBroadcaster's class name. -//          vEventMask          - (R) The mask of events to listen for. -// Return:  MIstatus::success - Functionality succeeded. -//          MIstatus::failure - Functionality failed. -// Throws:  None. -//-- -bool CMICmnLLDBDebugger::RegisterForEvent( -    const CMIUtilString &vClientName, const CMIUtilString &vBroadcasterClass, -    const MIuint vEventMask) { -  MIuint existingMask = 0; -  if (!BroadcasterGetMask(vBroadcasterClass, existingMask)) -    return MIstatus::failure; - -  if (!ClientSaveMask(vClientName, vBroadcasterClass, vEventMask)) -    return MIstatus::failure; - -  const char *pBroadCasterName = vBroadcasterClass.c_str(); -  MIuint eventMask = vEventMask; -  eventMask += existingMask; -  const MIuint result = m_lldbListener.StartListeningForEventClass( -      m_lldbDebugger, pBroadCasterName, eventMask); -  if (result == 0) { -    SetErrorDescription(CMIUtilString::Format( -        MIRSRC(IDS_LLDBDEBUGGER_ERR_STARTLISTENER), pBroadCasterName)); -    return MIstatus::failure; -  } - -  return BroadcasterSaveMask(vBroadcasterClass, eventMask); -} - -//++ -// Details: Register with the debugger, the SBListener, the type of events you -// are interested -//          in. Others, like commands, may have already set the mask. -// Type:    Method. -// Args:    vClientName     - (R) ID of the client who wants these events set. -//          vBroadcaster    - (R) An SBBroadcaster's derived class. -//          vEventMask      - (R) The mask of events to listen for. -// Return:  MIstatus::success - Functionality succeeded. -//          MIstatus::failure - Functionality failed. -// Throws:  None. -//-- -bool CMICmnLLDBDebugger::RegisterForEvent( -    const CMIUtilString &vClientName, const lldb::SBBroadcaster &vBroadcaster, -    const MIuint vEventMask) { -  const char *pBroadcasterName = vBroadcaster.GetName(); -  if (pBroadcasterName == nullptr) { -    SetErrorDescription( -        CMIUtilString::Format(MIRSRC(IDS_LLDBDEBUGGER_ERR_BROADCASTER_NAME), -                              MIRSRC(IDS_WORD_INVALIDNULLPTR))); -    return MIstatus::failure; -  } -  CMIUtilString broadcasterName(pBroadcasterName); -  if (broadcasterName.length() == 0) { -    SetErrorDescription( -        CMIUtilString::Format(MIRSRC(IDS_LLDBDEBUGGER_ERR_BROADCASTER_NAME), -                              MIRSRC(IDS_WORD_INVALIDEMPTY))); -    return MIstatus::failure; -  } - -  MIuint existingMask = 0; -  if (!BroadcasterGetMask(broadcasterName, existingMask)) -    return MIstatus::failure; - -  if (!ClientSaveMask(vClientName, broadcasterName, vEventMask)) -    return MIstatus::failure; - -  MIuint eventMask = vEventMask; -  eventMask += existingMask; -  const MIuint result = -      m_lldbListener.StartListeningForEvents(vBroadcaster, eventMask); -  if (result == 0) { -    SetErrorDescription(CMIUtilString::Format( -        MIRSRC(IDS_LLDBDEBUGGER_ERR_STARTLISTENER), pBroadcasterName)); -    return MIstatus::failure; -  } - -  return BroadcasterSaveMask(broadcasterName, eventMask); -} - -//++ -// Details: Unregister with the debugger, the SBListener, the type of events you -// are no -//          longer interested in. Others, like commands, may still remain -//          interested so -//          an event may not necessarily be stopped. -// Type:    Method. -// Args:    vClientName         - (R) ID of the client who no longer requires -// these events. -//          vBroadcasterClass   - (R) The SBBroadcaster's class name. -// Return:  MIstatus::success - Functionality succeeded. -//          MIstatus::failure - Functionality failed. -// Throws:  None. -//-- -bool CMICmnLLDBDebugger::UnregisterForEvent( -    const CMIUtilString &vClientName, const CMIUtilString &vBroadcasterClass) { -  MIuint clientsEventMask = 0; -  if (!ClientGetTheirMask(vClientName, vBroadcasterClass, clientsEventMask)) -    return MIstatus::failure; -  if (!ClientRemoveTheirMask(vClientName, vBroadcasterClass)) -    return MIstatus::failure; - -  const MIuint otherClientsEventMask = -      ClientGetMaskForAllClients(vBroadcasterClass); -  MIuint newEventMask = 0; -  for (MIuint i = 0; i < 32; i++) { -    const MIuint bit = MIuint(1) << i; -    const MIuint clientBit = bit & clientsEventMask; -    const MIuint othersBit = bit & otherClientsEventMask; -    if ((clientBit != 0) && (othersBit == 0)) { -      newEventMask += clientBit; -    } -  } - -  const char *pBroadCasterName = vBroadcasterClass.c_str(); -  if (!m_lldbListener.StopListeningForEventClass( -          m_lldbDebugger, pBroadCasterName, newEventMask)) { -    SetErrorDescription( -        CMIUtilString::Format(MIRSRC(IDS_LLDBDEBUGGER_ERR_STOPLISTENER), -                              vClientName.c_str(), pBroadCasterName)); -    return MIstatus::failure; -  } - -  return BroadcasterSaveMask(vBroadcasterClass, otherClientsEventMask); -} - -//++ -// Details: Given the SBBroadcaster class name retrieve it's current event mask. -// Type:    Method. -// Args:    vBroadcasterClass   - (R) The SBBroadcaster's class name. -//          vEventMask          - (W) The mask of events to listen for. -// Return:  MIstatus::success - Functionality succeeded. -//          MIstatus::failure - Functionality failed. -// Throws:  None. -//-- -bool CMICmnLLDBDebugger::BroadcasterGetMask( -    const CMIUtilString &vBroadcasterClass, MIuint &vwEventMask) const { -  vwEventMask = 0; - -  if (vBroadcasterClass.empty()) { -    SetErrorDescription( -        CMIUtilString::Format(MIRSRC(IDS_LLDBDEBUGGER_ERR_INVALIDBROADCASTER), -                              vBroadcasterClass.c_str())); -    return MIstatus::failure; -  } - -  const MapBroadcastClassNameToEventMask_t::const_iterator it = -      m_mapBroadcastClassNameToEventMask.find(vBroadcasterClass); -  if (it != m_mapBroadcastClassNameToEventMask.end()) { -    vwEventMask = (*it).second; -  } - -  return MIstatus::success; -} - -//++ -// Details: Remove the event mask for the specified SBBroadcaster class name. -// Type:    Method. -// Args:    vBroadcasterClass - (R) The SBBroadcaster's class name. -// Return:  MIstatus::success - Functionality succeeded. -//          MIstatus::failure - Functionality failed. -// Throws:  None. -//-- -bool CMICmnLLDBDebugger::BroadcasterRemoveMask( -    const CMIUtilString &vBroadcasterClass) { -  MapBroadcastClassNameToEventMask_t::const_iterator it = -      m_mapBroadcastClassNameToEventMask.find(vBroadcasterClass); -  if (it != m_mapBroadcastClassNameToEventMask.end()) { -    m_mapBroadcastClassNameToEventMask.erase(it); -  } - -  return MIstatus::success; -} - -//++ -// Details: Given the SBBroadcaster class name save it's current event mask. -// Type:    Method. -// Args:    vBroadcasterClass - (R) The SBBroadcaster's class name. -//          vEventMask        - (R) The mask of events to listen for. -// Return:  MIstatus::success - Functionality succeeded. -//          MIstatus::failure - Functionality failed. -// Throws:  None. -//-- -bool CMICmnLLDBDebugger::BroadcasterSaveMask( -    const CMIUtilString &vBroadcasterClass, const MIuint vEventMask) { -  if (vBroadcasterClass.empty()) { -    SetErrorDescription( -        CMIUtilString::Format(MIRSRC(IDS_LLDBDEBUGGER_ERR_INVALIDBROADCASTER), -                              vBroadcasterClass.c_str())); -    return MIstatus::failure; -  } - -  BroadcasterRemoveMask(vBroadcasterClass); -  MapPairBroadcastClassNameToEventMask_t pr(vBroadcasterClass, vEventMask); -  m_mapBroadcastClassNameToEventMask.insert(pr); - -  return MIstatus::success; -} - -//++ -// Details: Iterate all the clients who have registered event masks against -// particular -//          SBBroadcasters and build up the mask that is for all of them. -// Type:    Method. -// Args:    vBroadcasterClass   - (R) The broadcaster to retrieve the mask for. -// Return:  MIuint - Event mask. -// Throws:  None. -//-- -MIuint CMICmnLLDBDebugger::ClientGetMaskForAllClients( -    const CMIUtilString &vBroadcasterClass) const { -  MIuint mask = 0; -  MapIdToEventMask_t::const_iterator it = m_mapIdToEventMask.begin(); -  while (it != m_mapIdToEventMask.end()) { -    const CMIUtilString &rId((*it).first); -    if (rId.find(vBroadcasterClass) != std::string::npos) { -      const MIuint clientsMask = (*it).second; -      mask |= clientsMask; -    } - -    // Next -    ++it; -  } - -  return mask; -} - -//++ -// Details: Given the client save its particular event requirements. -// Type:    Method. -// Args:    vClientName       - (R) The Client's unique ID. -//          vBroadcasterClass - (R) The SBBroadcaster's class name targeted for -//          the events. -//          vEventMask        - (R) The mask of events to listen for. -// Return:  MIstatus::success - Functionality succeeded. -//          MIstatus::failure - Functionality failed. -// Throws:  None. -//-- -bool CMICmnLLDBDebugger::ClientSaveMask(const CMIUtilString &vClientName, -                                        const CMIUtilString &vBroadcasterClass, -                                        const MIuint vEventMask) { -  if (vClientName.empty()) { -    SetErrorDescription(CMIUtilString::Format( -        MIRSRC(IDS_LLDBDEBUGGER_ERR_INVALIDCLIENTNAME), vClientName.c_str())); -    return MIstatus::failure; -  } - -  CMIUtilString strId(vBroadcasterClass); -  strId += vClientName; - -  ClientRemoveTheirMask(vClientName, vBroadcasterClass); -  MapPairIdToEventMask_t pr(strId, vEventMask); -  m_mapIdToEventMask.insert(pr); - -  return MIstatus::success; -} - -//++ -// Details: Given the client remove it's particular event requirements. -// Type:    Method. -// Args:    vClientName       - (R) The Client's unique ID. -//          vBroadcasterClass - (R) The SBBroadcaster's class name. -// Return:  MIstatus::success - Functionality succeeded. -//          MIstatus::failure - Functionality failed. -// Throws:  None. -//-- -bool CMICmnLLDBDebugger::ClientRemoveTheirMask( -    const CMIUtilString &vClientName, const CMIUtilString &vBroadcasterClass) { -  if (vClientName.empty()) { -    SetErrorDescription(CMIUtilString::Format( -        MIRSRC(IDS_LLDBDEBUGGER_ERR_INVALIDCLIENTNAME), vClientName.c_str())); -    return MIstatus::failure; -  } - -  CMIUtilString strId(vBroadcasterClass); -  strId += vClientName; - -  const MapIdToEventMask_t::const_iterator it = m_mapIdToEventMask.find(strId); -  if (it != m_mapIdToEventMask.end()) { -    m_mapIdToEventMask.erase(it); -  } - -  return MIstatus::success; -} - -//++ -// Details: Retrieve the client's event mask used for on a particular -// SBBroadcaster. -// Type:    Method. -// Args:    vClientName       - (R) The Client's unique ID. -//          vBroadcasterClass - (R) The SBBroadcaster's class name. -//          vwEventMask       - (W) The client's mask. -// Return:  MIstatus::success - Functionality succeeded. -//          MIstatus::failure - Functionality failed. -// Throws:  None. -//-- -bool CMICmnLLDBDebugger::ClientGetTheirMask( -    const CMIUtilString &vClientName, const CMIUtilString &vBroadcasterClass, -    MIuint &vwEventMask) { -  vwEventMask = 0; - -  if (vClientName.empty()) { -    SetErrorDescription(CMIUtilString::Format( -        MIRSRC(IDS_LLDBDEBUGGER_ERR_INVALIDCLIENTNAME), vClientName.c_str())); -    return MIstatus::failure; -  } - -  const CMIUtilString strId(vBroadcasterClass + vClientName); -  const MapIdToEventMask_t::const_iterator it = m_mapIdToEventMask.find(strId); -  if (it != m_mapIdToEventMask.end()) { -    vwEventMask = (*it).second; -  } - -  SetErrorDescription(CMIUtilString::Format( -      MIRSRC(IDS_LLDBDEBUGGER_ERR_CLIENTNOTREGISTERED), vClientName.c_str())); - -  return MIstatus::failure; -} - -//++ -// Details: Momentarily wait for an events being broadcast and inspect those -// that do -//          come this way. Check if the target should exit event if so start -//          shutting -//          down this thread and the application. Any other events pass on to -//          the -//          Out-of-band handler to further determine what kind of event arrived. -//          This function runs in the thread "MI debugger event". -// Type:    Method. -// Args:    vrbIsAlive  - (W) False = yes exit event monitoring thread, true = -// continue. -// Return:  MIstatus::success - Functional succeeded. -//          MIstatus::failure - Functional failed. -// Throws:  None. -//-- -bool CMICmnLLDBDebugger::MonitorSBListenerEvents(bool &vrbIsAlive) { -  vrbIsAlive = true; - -  // Lock the mutex of event queue -  // Note that it should be locked while we are in -  // CMICmnLLDBDebugger::MonitorSBListenerEvents to -  // avoid a race condition with CMICmnLLDBDebugger::WaitForHandleEvent -  std::unique_lock<std::mutex> lock(m_mutexEventQueue); - -  lldb::SBEvent event; -  const bool bGotEvent = m_lldbListener.GetNextEvent(event); -  if (!bGotEvent) { -    // Notify that we are finished and unlock the mutex of event queue before -    // sleeping -    m_conditionEventQueueEmpty.notify_one(); -    lock.unlock(); - -    // Wait a bit to reduce CPU load -    const std::chrono::milliseconds time(1); -    std::this_thread::sleep_for(time); -    return MIstatus::success; -  } -  assert(event.IsValid()); -  assert(event.GetBroadcaster().IsValid()); - -  // Debugging -  m_pLog->WriteLog(CMIUtilString::Format("##### An event occurred: %s", -                                         event.GetBroadcasterClass())); - -  bool bHandledEvent = false; -  bool bOk = false; -  { -    // Lock Mutex before handling events so that we don't disturb a running cmd -    CMIUtilThreadLock lock( -        CMICmnLLDBDebugSessionInfo::Instance().GetSessionMutex()); -    bOk = CMICmnLLDBDebuggerHandleEvents::Instance().HandleEvent(event, -                                                                 bHandledEvent); -  } - -  if (!bHandledEvent) { -    const CMIUtilString msg( -        CMIUtilString::Format(MIRSRC(IDS_LLDBDEBUGGER_WRN_UNKNOWN_EVENT), -                              event.GetBroadcasterClass())); -    m_pLog->WriteLog(msg); -  } - -  if (!bOk) -    m_pLog->WriteLog( -        CMICmnLLDBDebuggerHandleEvents::Instance().GetErrorDescription()); - -  return MIstatus::success; -} - -//++ -// Details: The main worker method for this thread. -// Type:    Method. -// Args:    vrbIsAlive  - (W) True = *this thread is working, false = thread has -// exited. -// Return:  MIstatus::success - Functional succeeded. -//          MIstatus::failure - Functional failed. -// Throws:  None. -//-- -bool CMICmnLLDBDebugger::ThreadRun(bool &vrbIsAlive) { -  return MonitorSBListenerEvents(vrbIsAlive); -} - -//++ -// Details: Let this thread clean up after itself. -// Type:    Method. -// Args: -// Return:  MIstatus::success - Functionality succeeded. -//          MIstatus::failure - Functionality failed. -// Throws:  None. -//-- -bool CMICmnLLDBDebugger::ThreadFinish() { return MIstatus::success; } - -//++ -// Details: Retrieve *this thread object's name. -// Type:    Overridden. -// Args:    None. -// Return:  CMIUtilString & - Text. -// Throws:  None. -//-- -const CMIUtilString &CMICmnLLDBDebugger::ThreadGetName() const { -  return m_constStrThisThreadId; -} - -//++ -// Details: Loads lldb-mi formatters -// Type:    Method. -// Args:    None. -// Return:  true - Functionality succeeded. -//          false - Functionality failed. -// Throws:  None. -//-- -bool CMICmnLLDBDebugger::LoadMIFormatters(lldb::SBTypeCategory miCategory) { -  if (!MI_add_summary(miCategory, "char", MI_char_summary_provider, -                      lldb::eTypeOptionHideValue | -                          lldb::eTypeOptionSkipPointers)) -    return false; - -  if (!MI_add_summary(miCategory, "unsigned char", MI_char_summary_provider, -                      lldb::eTypeOptionHideValue | -                          lldb::eTypeOptionSkipPointers)) -    return false; - -  if (!MI_add_summary(miCategory, "signed char", MI_char_summary_provider, -                      lldb::eTypeOptionHideValue | -                          lldb::eTypeOptionSkipPointers)) -    return false; - -  return true; -} - -//++ -// Details: Registers lldb-mi custom summary providers -// Type:    Method. -// Args:    None. -// Return:  true - Functionality succeeded. -//          false - Functionality failed. -// Throws:  None. -//-- -bool CMICmnLLDBDebugger::RegisterMISummaryProviders() { -  static const char *miCategoryName = "lldb-mi"; -  lldb::SBTypeCategory miCategory = -      m_lldbDebugger.CreateCategory(miCategoryName); -  if (!miCategory.IsValid()) -    return false; - -  if (!LoadMIFormatters(miCategory)) { -    m_lldbDebugger.DeleteCategory(miCategoryName); -    return false; -  } -  miCategory.SetEnabled(true); -  return true; -} | 
