aboutsummaryrefslogtreecommitdiffstats
path: root/tools/lldb-mi/MICmnLLDBDebugger.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/lldb-mi/MICmnLLDBDebugger.cpp')
-rw-r--r--tools/lldb-mi/MICmnLLDBDebugger.cpp905
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;
-}