friend class SBBreakpoint;
friend class SBDebugger;
friend class SBProcess;
+ friend class SBTarget;
friend class SBThread;
friend class SBWatchpoint;
GetVersion (uint32_t *versions,
uint32_t num_versions);
+ //------------------------------------------------------------------
+ /// Get accessor for the symbol file specification.
+ ///
+ /// When debugging an object file an additional debug information can
+ /// be provided in separate file. Therefore if you debugging something
+ /// like '/usr/lib/liba.dylib' then debug information can be located
+ /// in folder like '/usr/lib/liba.dylib.dSYM/'.
+ ///
+ /// @return
+ /// A const reference to the file specification object.
+ //------------------------------------------------------------------
+ lldb::SBFileSpec
+ GetSymbolFileSpec() const;
+
+ lldb::SBAddress
+ GetObjectFileHeaderAddress() const;
+
private:
friend class SBAddress;
friend class SBFrame;
bool
IsValid() const;
+
+ static bool
+ EventIsTargetEvent (const lldb::SBEvent &event);
+
+ static lldb::SBTarget
+ GetTargetFromEvent (const lldb::SBEvent &event);
+ static uint32_t
+ GetNumModulesFromEvent (const lldb::SBEvent &event);
+
+ static lldb::SBModule
+ GetModuleAtIndexFromEvent (const uint32_t idx, const lldb::SBEvent &event);
+
static const char *
GetBroadcasterClassName ();
{
return GetStaticBroadcasterClass();
}
+
+ // This event data class is for use by the TargetList to broadcast new target notifications.
+ class TargetEventData : public EventData
+ {
+ public:
+ TargetEventData (const lldb::TargetSP &target_sp);
+
+ TargetEventData (const lldb::TargetSP &target_sp, const ModuleList &module_list);
+
+ virtual
+ ~TargetEventData();
+
+ static const ConstString &
+ GetFlavorString ();
+
+ virtual const ConstString &
+ GetFlavor () const
+ {
+ return TargetEventData::GetFlavorString ();
+ }
+
+ virtual void
+ Dump (Stream *s) const;
+
+ static const TargetEventData *
+ GetEventDataFromEvent (const Event *event_ptr);
+
+ static lldb::TargetSP
+ GetTargetFromEvent (const Event *event_ptr);
+
+ static ModuleList
+ GetModuleListFromEvent (const Event *event_ptr);
+
+ const lldb::TargetSP &
+ GetTarget() const
+ {
+ return m_target_sp;
+ }
+
+ const ModuleList &
+ GetModuleList() const
+ {
+ return m_module_list;
+ }
+
+ private:
+ lldb::TargetSP m_target_sp;
+ ModuleList m_module_list;
+
+ DISALLOW_COPY_AND_ASSIGN (TargetEventData);
+ };
static void
SettingsInitialize ();
}
}
+lldb::SBFileSpec
+SBModule::GetSymbolFileSpec() const
+{
+ lldb::SBFileSpec sb_file_spec;
+ ModuleSP module_sp(GetSP());
+ if (module_sp)
+ {
+ SymbolVendor *symbol_vendor_ptr = module_sp->GetSymbolVendor();
+ if (symbol_vendor_ptr)
+ sb_file_spec.SetFileSpec(symbol_vendor_ptr->GetMainFileSpec());
+ }
+ return sb_file_spec;
+}
+
+lldb::SBAddress
+SBModule::GetObjectFileHeaderAddress() const
+{
+ lldb::SBAddress sb_addr;
+ ModuleSP module_sp (GetSP ());
+ if (module_sp)
+ {
+ ObjectFile *objfile_ptr = module_sp->GetObjectFile();
+ if (objfile_ptr)
+ sb_addr.ref() = objfile_ptr->GetHeaderAddress();
+ }
+ return sb_addr;
+}
#include "lldb/lldb-public.h"
-#include "lldb/API/SBDebugger.h"
#include "lldb/API/SBBreakpoint.h"
+#include "lldb/API/SBDebugger.h"
+#include "lldb/API/SBEvent.h"
#include "lldb/API/SBExpressionOptions.h"
#include "lldb/API/SBFileSpec.h"
#include "lldb/API/SBListener.h"
{
}
+bool
+SBTarget::EventIsTargetEvent (const SBEvent &event)
+{
+ return Target::TargetEventData::GetEventDataFromEvent(event.get()) != NULL;
+}
+
+SBTarget
+SBTarget::GetTargetFromEvent (const SBEvent &event)
+{
+ return Target::TargetEventData::GetTargetFromEvent (event.get());
+}
+
+uint32_t
+SBTarget::GetNumModulesFromEvent (const SBEvent &event)
+{
+ const ModuleList module_list = Target::TargetEventData::GetModuleListFromEvent (event.get());
+ return module_list.GetSize();
+}
+
+SBModule
+SBTarget::GetModuleAtIndexFromEvent (const uint32_t idx, const SBEvent &event)
+{
+ const ModuleList module_list = Target::TargetEventData::GetModuleListFromEvent (event.get());
+ return SBModule(module_list.GetModuleAtIndex(idx));
+}
+
const char *
SBTarget::GetBroadcasterClassName ()
{
using namespace lldb;
using namespace lldb_private;
-namespace {
-// This event data class is for use by the TargetList to broadcast new target notifications.
-class TargetEventData : public EventData
-{
-public:
- TargetEventData(const lldb::TargetSP &new_target_sp)
- : EventData()
- , m_target_sp(new_target_sp)
- {
- }
-
- virtual ~TargetEventData()
- {
- }
-
- static const ConstString &
- GetFlavorString()
- {
- static ConstString g_flavor("Target::TargetEventData");
- return g_flavor;
- }
-
- virtual const ConstString &
- GetFlavor() const
- {
- return GetFlavorString();
- }
-
- lldb::TargetSP &
- GetTarget()
- {
- return m_target_sp;
- }
-
- virtual void
- Dump(Stream *s) const
- {
- }
-
- static const lldb::TargetSP
- GetTargetFromEvent(const lldb::EventSP &event_sp)
- {
- TargetSP target_sp;
-
- const TargetEventData *data = GetEventDataFromEvent (event_sp.get());
- if (data)
- target_sp = data->m_target_sp;
-
- return target_sp;
- }
-
- static const TargetEventData *
- GetEventDataFromEvent(const Event *event_ptr)
- {
- if (event_ptr)
- {
- const EventData *event_data = event_ptr->GetData();
- if (event_data && event_data->GetFlavor() == TargetEventData::GetFlavorString())
- return static_cast <const TargetEventData *> (event_ptr->GetData());
- }
- return nullptr;
- }
-
-private:
- lldb::TargetSP m_target_sp;
-
- DISALLOW_COPY_AND_ASSIGN (TargetEventData);
-};
-}
-
ConstString &
Target::GetStaticBroadcasterClass ()
{
{
m_process_sp->ModulesDidLoad (module_list);
}
- // TODO: make event data that packages up the module_list
- BroadcastEvent (eBroadcastBitModulesLoaded, NULL);
+ BroadcastEvent (eBroadcastBitModulesLoaded, new TargetEventData (this->shared_from_this(), module_list));
}
}
}
m_breakpoint_list.UpdateBreakpoints (module_list, true, false);
- BroadcastEvent(eBroadcastBitSymbolsLoaded, NULL);
+ BroadcastEvent (eBroadcastBitSymbolsLoaded, new TargetEventData (this->shared_from_this(), module_list));
}
}
{
UnloadModuleSections (module_list);
m_breakpoint_list.UpdateBreakpoints (module_list, false, delete_locations);
- // TODO: make event data that packages up the module_list
- BroadcastEvent (eBroadcastBitModulesUnloaded, NULL);
+ BroadcastEvent (eBroadcastBitModulesUnloaded, new TargetEventData (this->shared_from_this(), module_list));
}
}
else
this_->m_launch_info.GetFlags().Clear(lldb::eLaunchFlagDisableSTDIO);
}
+
+//----------------------------------------------------------------------
+// Target::TargetEventData
+//----------------------------------------------------------------------
+
+Target::TargetEventData::TargetEventData (const lldb::TargetSP &target_sp) :
+ EventData (),
+ m_target_sp (target_sp),
+ m_module_list ()
+{
+}
+
+Target::TargetEventData::TargetEventData (const lldb::TargetSP &target_sp, const ModuleList &module_list) :
+ EventData (),
+ m_target_sp (target_sp),
+ m_module_list (module_list)
+{
+}
+
+Target::TargetEventData::~TargetEventData()
+{
+}
+
+const ConstString &
+Target::TargetEventData::GetFlavorString ()
+{
+ static ConstString g_flavor ("Target::TargetEventData");
+ return g_flavor;
+}
+
+void
+Target::TargetEventData::Dump (Stream *s) const
+{
+}
+
+const Target::TargetEventData *
+Target::TargetEventData::GetEventDataFromEvent (const Event *event_ptr)
+{
+ if (event_ptr)
+ {
+ const EventData *event_data = event_ptr->GetData();
+ if (event_data && event_data->GetFlavor() == TargetEventData::GetFlavorString())
+ return static_cast <const TargetEventData *> (event_ptr->GetData());
+ }
+ return NULL;
+}
+
+TargetSP
+Target::TargetEventData::GetTargetFromEvent (const Event *event_ptr)
+{
+ TargetSP target_sp;
+ const TargetEventData *event_data = GetEventDataFromEvent (event_ptr);
+ if (event_data)
+ target_sp = event_data->m_target_sp;
+ return target_sp;
+}
+
+ModuleList
+Target::TargetEventData::GetModuleListFromEvent (const Event *event_ptr)
+{
+ ModuleList module_list;
+ const TargetEventData *event_data = GetEventDataFromEvent (event_ptr);
+ if (event_data)
+ module_list = event_data->m_module_list;
+ return module_list;
+}
}
const CMIUtilString strDbgId("CMICmnLLDBDebugger1");
- MIuint eventMask = lldb::SBTarget::eBroadcastBitBreakpointChanged;
+ 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;
//--
// Third party headers:
+#include "lldb/API/SBAddress.h"
#include "lldb/API/SBEvent.h"
#include "lldb/API/SBProcess.h"
#include "lldb/API/SBBreakpoint.h"
#include "lldb/API/SBStream.h"
+#include "lldb/API/SBTarget.h"
#include "lldb/API/SBThread.h"
#include "lldb/API/SBCommandInterpreter.h"
#include "lldb/API/SBCommandReturnObject.h"
vrbHandledEvent = true;
bOk = HandleEventSBThread(vEvent);
}
+ else if (lldb::SBTarget::EventIsTargetEvent(vEvent))
+ {
+ vrbHandledEvent = true;
+ bOk = HandleEventSBTarget(vEvent);
+ }
return bOk;
}
}
//++ ------------------------------------------------------------------------------------
+// Details: Handle a LLDB SBTarget event.
+// Type: Method.
+// Args: vEvent - (R) An LLDB broadcast event.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool
+CMICmnLLDBDebuggerHandleEvents::HandleEventSBTarget(const lldb::SBEvent &vEvent)
+{
+ if (!ChkForStateChanges())
+ return MIstatus::failure;
+
+ bool bOk = MIstatus::success;
+ const MIchar *pEventType = "";
+ const MIuint nEventType = vEvent.GetType();
+ switch (nEventType)
+ {
+ case lldb::SBTarget::eBroadcastBitBreakpointChanged:
+ pEventType = "eBroadcastBitBreakpointChanged";
+ break;
+ case lldb::SBTarget::eBroadcastBitModulesLoaded:
+ pEventType = "eBroadcastBitModulesLoaded";
+ bOk = HandleTargetEventBroadcastBitModulesLoaded(vEvent);
+ break;
+ case lldb::SBTarget::eBroadcastBitModulesUnloaded:
+ pEventType = "eBroadcastBitModulesUnloaded";
+ bOk = HandleTargetEventBroadcastBitModulesUnloaded(vEvent);
+ break;
+ case lldb::SBTarget::eBroadcastBitWatchpointChanged:
+ pEventType = "eBroadcastBitWatchpointChanged";
+ break;
+ case lldb::SBTarget::eBroadcastBitSymbolsLoaded:
+ pEventType = "eBroadcastBitSymbolsLoaded";
+ break;
+ default:
+ {
+ const CMIUtilString msg(CMIUtilString::Format(MIRSRC(IDS_LLDBOUTOFBAND_ERR_UNKNOWN_EVENT), "SBTarget", (MIuint)nEventType));
+ SetErrorDescription(msg);
+ return MIstatus::failure;
+ }
+ }
+ m_pLog->WriteLog(CMIUtilString::Format("##### An SBTarget event occurred: %s", pEventType));
+
+ return bOk;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Print to stdout "=shlibs-added,shlib-info=[key=\"value\"...]"
+// Type: Method.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool
+CMICmnLLDBDebuggerHandleEvents::HandleTargetEventBroadcastBitModulesLoaded(const lldb::SBEvent &vEvent)
+{
+ static MIuint s_nModulesLoadedNumber(0);
+ const MIuint nSize(lldb::SBTarget::GetNumModulesFromEvent(vEvent));
+ bool bOk = MIstatus::success;
+ for (MIuint nIndex(0); bOk && (nIndex < nSize); ++nIndex)
+ {
+ const lldb::SBModule sbModule = lldb::SBTarget::GetModuleAtIndexFromEvent(nIndex, vEvent);
+ CMICmnMIValueList miValueList(true);
+ bOk = MiHelpGetModuleInfo(sbModule, ++s_nModulesLoadedNumber, miValueList);
+ const CMICmnMIValueResult miValueResult("shlib-info", miValueList);
+ const CMICmnMIOutOfBandRecord miOutOfBandRecord(CMICmnMIOutOfBandRecord::eOutOfBand_TargetModulesLoaded, miValueResult);
+ bOk = bOk && MiOutOfBandRecordToStdout(miOutOfBandRecord);
+ }
+
+ return bOk;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Print to stdout "=shlibs-removed,shlib-info=[key=\"value\"...]"
+// Type: Method.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool
+CMICmnLLDBDebuggerHandleEvents::HandleTargetEventBroadcastBitModulesUnloaded(const lldb::SBEvent &vEvent)
+{
+ static MIuint s_nModulesUnloadedNumber(0);
+ const MIuint nSize(lldb::SBTarget::GetNumModulesFromEvent(vEvent));
+ bool bOk = MIstatus::success;
+ for (MIuint nIndex(0); bOk && (nIndex < nSize); ++nIndex)
+ {
+ const lldb::SBModule sbModule = lldb::SBTarget::GetModuleAtIndexFromEvent(nIndex, vEvent);
+ CMICmnMIValueList miValueList(true);
+ bOk = MiHelpGetModuleInfo(sbModule, ++s_nModulesUnloadedNumber, miValueList);
+ const CMICmnMIValueResult miValueResult("shlib-info", miValueList);
+ const CMICmnMIOutOfBandRecord miOutOfBandRecord(CMICmnMIOutOfBandRecord::eOutOfBand_TargetModulesUnloaded, miValueResult);
+ bOk = bOk && MiOutOfBandRecordToStdout(miOutOfBandRecord);
+ }
+
+ return bOk;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Build module information for shlib-info "[num=\"%ld\",name=\"%s\",dyld-addr=\"%#lx\",reason=\"dyld\",path=\"%s\",loaded_addr=\"%#lx\",dsym-objpath=\"%s\"]"
+// Type: Method.
+// Args: vwrMiValueList - (W) MI value list object.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool
+CMICmnLLDBDebuggerHandleEvents::MiHelpGetModuleInfo(const lldb::SBModule &vModule, const MIuint nModuleNum,
+ CMICmnMIValueList &vwrMiValueList)
+{
+ bool bOk = MIstatus::success;
+
+ // Build "num" field
+ const CMIUtilString strNum(CMIUtilString::Format("%ld", nModuleNum));
+ const CMICmnMIValueConst miValueConst(strNum);
+ const CMICmnMIValueResult miValueResult("num", miValueConst);
+ bOk = bOk && vwrMiValueList.Add(miValueResult);
+ // Build "name" field
+ const CMICmnMIValueConst miValueConst2(vModule.GetPlatformFileSpec().GetFilename());
+ const CMICmnMIValueResult miValueResult2("name", miValueConst2);
+ bOk = bOk && vwrMiValueList.Add(miValueResult2);
+ // Build "dyld-addr" field
+ const lldb::SBAddress sbAddress(vModule.GetObjectFileHeaderAddress());
+ const CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
+ const lldb::addr_t nLoadAddress(sbAddress.GetLoadAddress(rSessionInfo.GetTarget()));
+ const CMIUtilString strDyldAddr(CMIUtilString::Format("%#lx", nLoadAddress));
+ const CMICmnMIValueConst miValueConst3(nLoadAddress != LLDB_INVALID_ADDRESS ? strDyldAddr : "-");
+ const CMICmnMIValueResult miValueResult3("dyld-addr", miValueConst3);
+ bOk = bOk && vwrMiValueList.Add(miValueResult3);
+ // Build "reason" field
+ const CMICmnMIValueConst miValueConst4("dyld");
+ const CMICmnMIValueResult miValueResult4("reason", miValueConst4);
+ bOk = bOk && vwrMiValueList.Add(miValueResult4);
+ // Build "path" field
+ char path[PATH_MAX];
+ vModule.GetPlatformFileSpec().GetPath(path, sizeof(path));
+ const CMIUtilString strPlatformPath(path);
+ const CMICmnMIValueConst miValueConst5(strPlatformPath);
+ const CMICmnMIValueResult miValueResult5("path", miValueConst5);
+ bOk = bOk && vwrMiValueList.Add(miValueResult5);
+ // Build "loaded_addr" field
+ const CMIUtilString strLoadedAddr(CMIUtilString::Format("%#lx", nLoadAddress));
+ const CMICmnMIValueConst miValueConst6(nLoadAddress != LLDB_INVALID_ADDRESS ? strDyldAddr : "-");
+ const CMICmnMIValueResult miValueResult6("loaded_addr", miValueConst6);
+ bOk = bOk && vwrMiValueList.Add(miValueResult6);
+ // Build "dsym-objpath" field
+ vModule.GetSymbolFileSpec().GetPath(path, sizeof(path));
+ const CMIUtilString strSymbolFilePath(path);
+ if (!CMIUtilString::Compare(strPlatformPath, strSymbolFilePath))
+ {
+ const CMICmnMIValueConst miValueConst7(strSymbolFilePath);
+ const CMICmnMIValueResult miValueResult7("dsym-objpath", miValueConst7);
+ bOk = bOk && vwrMiValueList.Add(miValueResult7);
+ }
+
+ return bOk;
+}
+
+//++ ------------------------------------------------------------------------------------
// Details: Handle a LLDB SBCommandInterpreter event.
// Type: Method.
// Args: vEvent - (R) An LLDB command interpreter event.
// In-house headers:
#include "MICmnBase.h"
+#include "MICmnMIValueList.h"
#include "MICmnMIValueTuple.h"
#include "MIUtilSingletonBase.h"
bool HandleEventSBBreakpointAdded(const lldb::SBEvent &vEvent);
bool HandleEventSBBreakpointLocationsAdded(const lldb::SBEvent &vEvent);
bool HandleEventSBProcess(const lldb::SBEvent &vEvent);
+ bool HandleEventSBTarget(const lldb::SBEvent &vEvent);
bool HandleEventSBThread(const lldb::SBEvent &vEvent);
bool HandleEventSBThreadBitStackChanged(const lldb::SBEvent &vEvent);
bool HandleEventSBThreadSuspended(const lldb::SBEvent &vEvent);
bool HandleProcessEventStopSignal(bool &vwrbShouldBrk);
bool HandleProcessEventStopException(void);
bool HandleProcessEventStateSuspended(const lldb::SBEvent &vEvent);
+ bool HandleTargetEventBroadcastBitModulesLoaded(const lldb::SBEvent &vEvent);
+ bool HandleTargetEventBroadcastBitModulesUnloaded(const lldb::SBEvent &vEvent);
+ bool MiHelpGetModuleInfo(const lldb::SBModule &vModule, const MIuint nModuleNum,
+ CMICmnMIValueList &vwrMiValueList);
bool MiHelpGetCurrentThreadFrame(CMICmnMIValueTuple &vwrMiValueTuple);
bool MiResultRecordToStdout(const CMICmnMIResultRecord &vrMiResultRecord);
bool MiOutOfBandRecordToStdout(const CMICmnMIOutOfBandRecord &vrMiResultRecord);
{CMICmnMIOutOfBandRecord::eOutOfBand_ThreadGroupStarted, "thread-group-started"},
{CMICmnMIOutOfBandRecord::eOutOfBand_ThreadCreated, "thread-created"},
{CMICmnMIOutOfBandRecord::eOutOfBand_ThreadExited, "thread-exited"},
- {CMICmnMIOutOfBandRecord::eOutOfBand_ThreadSelected, "thread-selected"}};
+ {CMICmnMIOutOfBandRecord::eOutOfBand_ThreadSelected, "thread-selected"},
+ {CMICmnMIOutOfBandRecord::eOutOfBand_TargetModulesLoaded, "shlibs-added"},
+ {CMICmnMIOutOfBandRecord::eOutOfBand_TargetModulesUnloaded, "shlibs-removed"}};
CMICmnMIOutOfBandRecord::MapOutOfBandToOutOfBandText_t ms_constMapAsyncRecordTextToToken = {
{CMICmnMIOutOfBandRecord::eOutOfBand_Running, "*"},
{CMICmnMIOutOfBandRecord::eOutOfBand_Stopped, "*"},
{CMICmnMIOutOfBandRecord::eOutOfBand_ThreadGroupStarted, "="},
{CMICmnMIOutOfBandRecord::eOutOfBand_ThreadCreated, "="},
{CMICmnMIOutOfBandRecord::eOutOfBand_ThreadExited, "="},
- {CMICmnMIOutOfBandRecord::eOutOfBand_ThreadSelected, "="}};
+ {CMICmnMIOutOfBandRecord::eOutOfBand_ThreadSelected, "="},
+ {CMICmnMIOutOfBandRecord::eOutOfBand_TargetModulesLoaded, "="},
+ {CMICmnMIOutOfBandRecord::eOutOfBand_TargetModulesUnloaded, "="}};
//++ ------------------------------------------------------------------------------------
// Details: CMICmnMIOutOfBandRecord constructor.
eOutOfBand_ThreadCreated,
eOutOfBand_ThreadExited,
eOutOfBand_ThreadSelected,
+ eOutOfBand_TargetModulesLoaded,
+ eOutOfBand_TargetModulesUnloaded,
eOutOfBand_count // Always the last one
};