Add a new system runtime plugin type - just the top level

class, not any actual plugin implementation yet.
<rdar://problem/15314068> 

llvm-svn: 194044
This commit is contained in:
Jason Molenda 2013-11-05 03:57:19 +00:00
parent d6b40b51c7
commit eef510667b
11 changed files with 365 additions and 1 deletions

View File

@ -131,6 +131,24 @@ public:
GetLanguageRuntimeCreateCallbackForPluginName (const ConstString &name);
//------------------------------------------------------------------
// SystemRuntime
//------------------------------------------------------------------
static bool
RegisterPlugin (const ConstString &name,
const char *description,
SystemRuntimeCreateInstance create_callback);
static bool
UnregisterPlugin (SystemRuntimeCreateInstance create_callback);
static SystemRuntimeCreateInstance
GetSystemRuntimeCreateCallbackAtIndex (uint32_t idx);
static SystemRuntimeCreateInstance
GetSystemRuntimeCreateCallbackForPluginName (const ConstString &name);
//------------------------------------------------------------------
// ObjectFile
//------------------------------------------------------------------

View File

@ -1757,7 +1757,7 @@ public:
error.SetErrorStringWithFormat("error: %s does not support loading core files.", GetPluginName().GetCString());
return error;
}
//------------------------------------------------------------------
/// Get the dynamic loader plug-in for this process.
///
@ -1770,6 +1770,16 @@ public:
virtual DynamicLoader *
GetDynamicLoader ();
//------------------------------------------------------------------
/// Get the system runtime plug-in for this process.
///
/// @return
/// Returns a pointer to the SystemRuntime plugin for this Process
/// if one is available. Else returns NULL.
//------------------------------------------------------------------
virtual SystemRuntime *
GetSystemRuntime ();
//------------------------------------------------------------------
/// Attach to an existing process using the process attach info.
///
@ -3667,6 +3677,7 @@ protected:
std::unique_ptr<DynamicLoader> m_dyld_ap;
std::unique_ptr<DynamicCheckerFunctions> m_dynamic_checkers_ap; ///< The functions used by the expression parser to validate data that expressions use.
std::unique_ptr<OperatingSystem> m_os_ap;
std::unique_ptr<SystemRuntime> m_system_runtime_ap;
UnixSignals m_unix_signals; /// This is the current signal set for this process.
lldb::ABISP m_abi_sp;
lldb::InputReaderSP m_process_input_reader;

View File

@ -0,0 +1,121 @@
//===-- SystemRuntime.h -----------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef liblldb_SystemRuntime_h_
#define liblldb_SystemRuntime_h_
// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/lldb-public.h"
#include "lldb/Core/ModuleList.h"
#include "lldb/Core/PluginInterface.h"
#include "lldb/lldb-private.h"
namespace lldb_private {
//----------------------------------------------------------------------
/// @class SystemRuntime SystemRuntime.h "lldb/Target/SystemRuntime.h"
/// @brief A plug-in interface definition class for system runtimes.
///
/// The system runtime plugins can collect information from the system
/// libraries during a Process' lifetime and provide information about
/// how objects/threads were originated.
///
/// For instance, a system runtime plugin use a breakpoint when threads
/// are created to record the backtrace of where that thread was created.
/// Later, when backtracing the created thread, it could extend the backtrace
/// to show where it was originally created from.
///
/// The plugin will insert its own breakpoint when Created and start collecting
/// information. Later when it comes time to augment a Thread, it can be
/// asked to provide that information.
///
//----------------------------------------------------------------------
class SystemRuntime :
public PluginInterface
{
public:
//------------------------------------------------------------------
/// Find a system runtime plugin for a given process.
///
/// Scans the installed SystemRuntime plugins and tries to find
/// an instance that can be used to track image changes in \a
/// process.
///
/// @param[in] process
/// The process for which to try and locate a system runtime
/// plugin instance.
//------------------------------------------------------------------
static SystemRuntime*
FindPlugin (Process *process);
//------------------------------------------------------------------
/// Construct with a process.
// -----------------------------------------------------------------
SystemRuntime(lldb_private::Process *process);
//------------------------------------------------------------------
/// Destructor.
///
/// The destructor is virtual since this class is designed to be
/// inherited by the plug-in instance.
//------------------------------------------------------------------
virtual
~SystemRuntime();
//------------------------------------------------------------------
/// Called after attaching to a process.
///
/// Allow the SystemRuntime plugin to execute some code after attaching
/// to a process.
//------------------------------------------------------------------
virtual void
DidAttach ();
//------------------------------------------------------------------
/// Called after launching a process.
///
/// Allow the SystemRuntime plugin to execute some code after launching
/// a process.
//------------------------------------------------------------------
virtual void
DidLaunch();
//------------------------------------------------------------------
/// Called when modules have been loaded in the process.
///
/// Allow the SystemRuntime plugin to enable logging features in the
/// system runtime libraries.
//------------------------------------------------------------------
virtual void
ModulesDidLoad(lldb_private::ModuleList &module_list);
//------------------------------------------------------------------
/// Call this method to print the backtrace of where this thread was
/// enqueued, if at all. Returns the number of frames printed.
//------------------------------------------------------------------
virtual uint32_t
GetStatus (lldb_private::Stream &strm, lldb_private::ExecutionContext &exe_ctx);
protected:
//------------------------------------------------------------------
// Member variables.
//------------------------------------------------------------------
Process *m_process;
private:
DISALLOW_COPY_AND_ASSIGN (SystemRuntime);
};
} // namespace lldb_private
#endif // liblldb_SystemRuntime_h_

View File

@ -106,6 +106,7 @@ class Instruction;
class InstructionList;
class IRExecutionUnit;
class LanguageRuntime;
class SystemRuntime;
class LineTable;
class Listener;
class Log;
@ -297,6 +298,7 @@ namespace lldb {
typedef std::shared_ptr<lldb_private::InputReader> InputReaderSP;
typedef std::shared_ptr<lldb_private::Instruction> InstructionSP;
typedef std::shared_ptr<lldb_private::LanguageRuntime> LanguageRuntimeSP;
typedef std::shared_ptr<lldb_private::SystemRuntime> SystemRuntimeSP;
typedef std::shared_ptr<lldb_private::LineTable> LineTableSP;
typedef std::shared_ptr<lldb_private::Listener> ListenerSP;
typedef std::shared_ptr<lldb_private::LogChannel> LogChannelSP;

View File

@ -27,6 +27,7 @@ namespace lldb_private
typedef EmulateInstruction * (*EmulateInstructionCreateInstance) (const ArchSpec &arch, InstructionType inst_type);
typedef OperatingSystem* (*OperatingSystemCreateInstance) (Process *process, bool force);
typedef LanguageRuntime *(*LanguageRuntimeCreateInstance) (Process *process, lldb::LanguageType language);
typedef SystemRuntime *(*SystemRuntimeCreateInstance) (Process *process);
typedef Platform* (*PlatformCreateInstance) (bool force, const ArchSpec *arch);
typedef lldb::ProcessSP (*ProcessCreateInstance) (Target &target, Listener &listener, const FileSpec *crash_file_path);
typedef SymbolFile* (*SymbolFileCreateInstance) (ObjectFile* obj_file);

View File

@ -602,6 +602,7 @@
AF254E31170CCC33007AE5C9 /* PlatformDarwinKernel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF254E2F170CCC33007AE5C9 /* PlatformDarwinKernel.cpp */; };
AF254E32170CCC33007AE5C9 /* PlatformDarwinKernel.h in Headers */ = {isa = PBXBuildFile; fileRef = AF254E30170CCC33007AE5C9 /* PlatformDarwinKernel.h */; };
AF37E10A17C861F20061E18E /* ProcessRunLock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF37E10917C861F20061E18E /* ProcessRunLock.cpp */; };
AF81DEFA1828A23F0042CF19 /* SystemRuntime.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF81DEF91828A23F0042CF19 /* SystemRuntime.cpp */; };
AF90106515AB7D3600FF120D /* lldb.1 in CopyFiles */ = {isa = PBXBuildFile; fileRef = AF90106315AB7C5700FF120D /* lldb.1 */; };
AFF87C87150FF669000E1742 /* com.apple.debugserver.plist in CopyFiles */ = {isa = PBXBuildFile; fileRef = AFF87C86150FF669000E1742 /* com.apple.debugserver.plist */; };
AFF87C89150FF672000E1742 /* com.apple.debugserver-secure.plist in CopyFiles */ = {isa = PBXBuildFile; fileRef = AFF87C88150FF672000E1742 /* com.apple.debugserver-secure.plist */; };
@ -1743,6 +1744,7 @@
AF68D2551255416E002FF25B /* RegisterContextLLDB.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RegisterContextLLDB.h; path = Utility/RegisterContextLLDB.h; sourceTree = "<group>"; };
AF68D32F1255A110002FF25B /* UnwindLLDB.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = UnwindLLDB.cpp; path = Utility/UnwindLLDB.cpp; sourceTree = "<group>"; };
AF68D3301255A110002FF25B /* UnwindLLDB.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = UnwindLLDB.h; path = Utility/UnwindLLDB.h; sourceTree = "<group>"; };
AF81DEF91828A23F0042CF19 /* SystemRuntime.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SystemRuntime.cpp; path = source/Target/SystemRuntime.cpp; sourceTree = "<group>"; };
AF90106315AB7C5700FF120D /* lldb.1 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.man; name = lldb.1; path = docs/lldb.1; sourceTree = "<group>"; };
AF94005711C03F6500085DB9 /* SymbolVendor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SymbolVendor.cpp; path = source/Symbol/SymbolVendor.cpp; sourceTree = "<group>"; };
AFF87C86150FF669000E1742 /* com.apple.debugserver.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = com.apple.debugserver.plist; path = tools/debugserver/source/com.apple.debugserver.plist; sourceTree = "<group>"; };
@ -3110,6 +3112,7 @@
26BC7F3A10F1B90C00F91463 /* StackID.cpp */,
2615DB841208A9C90021781D /* StopInfo.h */,
2615DB861208A9E40021781D /* StopInfo.cpp */,
AF81DEF91828A23F0042CF19 /* SystemRuntime.cpp */,
26BC7DF810F1B81A00F91463 /* Target.h */,
26BC7F3B10F1B90C00F91463 /* Target.cpp */,
26BC7DF910F1B81A00F91463 /* TargetList.h */,
@ -4266,6 +4269,7 @@
26ECA04313665FED008D1F18 /* ARM_DWARF_Registers.cpp in Sources */,
267C012B136880DF006E963E /* OptionGroupValueObjectDisplay.cpp in Sources */,
26BCFC521368AE38006DC050 /* OptionGroupFormat.cpp in Sources */,
AF81DEFA1828A23F0042CF19 /* SystemRuntime.cpp in Sources */,
267C01371368C49C006E963E /* OptionGroupOutputFile.cpp in Sources */,
260E07C6136FA69E00CF21D3 /* OptionGroupUUID.cpp in Sources */,
260E07C8136FAB9200CF21D3 /* OptionGroupFile.cpp in Sources */,

View File

@ -854,6 +854,111 @@ PluginManager::GetLanguageRuntimeCreateCallbackForPluginName (const ConstString
return NULL;
}
#pragma mark SystemRuntime
struct SystemRuntimeInstance
{
SystemRuntimeInstance() :
name(),
description(),
create_callback(NULL)
{
}
ConstString name;
std::string description;
SystemRuntimeCreateInstance create_callback;
};
typedef std::vector<SystemRuntimeInstance> SystemRuntimeInstances;
static Mutex &
GetSystemRuntimeMutex ()
{
static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
return g_instances_mutex;
}
static SystemRuntimeInstances &
GetSystemRuntimeInstances ()
{
static SystemRuntimeInstances g_instances;
return g_instances;
}
bool
PluginManager::RegisterPlugin
(
const ConstString &name,
const char *description,
SystemRuntimeCreateInstance create_callback
)
{
if (create_callback)
{
SystemRuntimeInstance instance;
assert ((bool)name);
instance.name = name;
if (description && description[0])
instance.description = description;
instance.create_callback = create_callback;
Mutex::Locker locker (GetSystemRuntimeMutex ());
GetSystemRuntimeInstances ().push_back (instance);
}
return false;
}
bool
PluginManager::UnregisterPlugin (SystemRuntimeCreateInstance create_callback)
{
if (create_callback)
{
Mutex::Locker locker (GetSystemRuntimeMutex ());
SystemRuntimeInstances &instances = GetSystemRuntimeInstances ();
SystemRuntimeInstances::iterator pos, end = instances.end();
for (pos = instances.begin(); pos != end; ++ pos)
{
if (pos->create_callback == create_callback)
{
instances.erase(pos);
return true;
}
}
}
return false;
}
SystemRuntimeCreateInstance
PluginManager::GetSystemRuntimeCreateCallbackAtIndex (uint32_t idx)
{
Mutex::Locker locker (GetSystemRuntimeMutex ());
SystemRuntimeInstances &instances = GetSystemRuntimeInstances ();
if (idx < instances.size())
return instances[idx].create_callback;
return NULL;
}
SystemRuntimeCreateInstance
PluginManager::GetSystemRuntimeCreateCallbackForPluginName (const ConstString &name)
{
if (name)
{
Mutex::Locker locker (GetSystemRuntimeMutex ());
SystemRuntimeInstances &instances = GetSystemRuntimeInstances ();
SystemRuntimeInstances::iterator pos, end = instances.end();
for (pos = instances.begin(); pos != end; ++ pos)
{
if (name == pos->name)
return pos->create_callback;
}
}
return NULL;
}
#pragma mark ObjectFile
struct ObjectFileInstance

View File

@ -19,6 +19,7 @@ add_lldb_library(lldbTarget
StackFrameList.cpp
StackID.cpp
StopInfo.cpp
SystemRuntime.cpp
Target.cpp
TargetList.cpp
Thread.cpp

View File

@ -35,6 +35,7 @@
#include "lldb/Target/Platform.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/StopInfo.h"
#include "lldb/Target/SystemRuntime.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/TargetList.h"
#include "lldb/Target/Thread.h"
@ -1143,6 +1144,7 @@ Process::Finalize()
m_dynamic_checkers_ap.reset();
m_abi_sp.reset();
m_os_ap.reset();
m_system_runtime_ap.reset();
m_dyld_ap.reset();
m_thread_list_real.Destroy();
m_thread_list.Destroy();
@ -2876,6 +2878,7 @@ Process::Launch (const ProcessLaunchInfo &launch_info)
Error error;
m_abi_sp.reset();
m_dyld_ap.reset();
m_system_runtime_ap.reset();
m_os_ap.reset();
m_process_input_reader.reset();
@ -2944,6 +2947,10 @@ Process::Launch (const ProcessLaunchInfo &launch_info)
if (dyld)
dyld->DidLaunch();
SystemRuntime *system_runtime = GetSystemRuntime ();
if (system_runtime)
system_runtime->DidLaunch();
m_os_ap.reset (OperatingSystem::FindPlugin (this, NULL));
// This delays passing the stopped event to listeners till DidLaunch gets
// a chance to complete...
@ -2987,6 +2994,10 @@ Process::LoadCore ()
if (dyld)
dyld->DidAttach();
SystemRuntime *system_runtime = GetSystemRuntime ();
if (system_runtime)
system_runtime->DidAttach();
m_os_ap.reset (OperatingSystem::FindPlugin (this, NULL));
// We successfully loaded a core file, now pretend we stopped so we can
// show all of the threads in the core file and explore the crashed
@ -3005,6 +3016,14 @@ Process::GetDynamicLoader ()
return m_dyld_ap.get();
}
SystemRuntime *
Process::GetSystemRuntime ()
{
if (m_system_runtime_ap.get() == NULL)
m_system_runtime_ap.reset (SystemRuntime::FindPlugin(this));
return m_system_runtime_ap.get();
}
Process::NextEventAction::EventActionResult
Process::AttachCompletionHandler::PerformAction (lldb::EventSP &event_sp)
@ -3067,6 +3086,7 @@ Process::Attach (ProcessAttachInfo &attach_info)
m_abi_sp.reset();
m_process_input_reader.reset();
m_dyld_ap.reset();
m_system_runtime_ap.reset();
m_os_ap.reset();
lldb::pid_t attach_pid = attach_info.GetProcessID();
@ -3239,6 +3259,10 @@ Process::CompleteAttach ()
if (dyld)
dyld->DidAttach();
SystemRuntime *system_runtime = GetSystemRuntime ();
if (system_runtime)
system_runtime->DidAttach();
m_os_ap.reset (OperatingSystem::FindPlugin (this, NULL));
// Figure out which one is the executable, and set that in our target:
const ModuleList &target_modules = m_target.GetImages();
@ -5614,6 +5638,7 @@ Process::DidExec ()
target.GetSectionLoadList().Clear();
m_dynamic_checkers_ap.reset();
m_abi_sp.reset();
m_system_runtime_ap.reset();
m_os_ap.reset();
m_dyld_ap.reset();
m_image_tokens.clear();

View File

@ -0,0 +1,67 @@
//===-- SystemRuntime.cpp ---------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "lldb/lldb-private.h"
#include "lldb/Target/SystemRuntime.h"
#include "lldb/Target/Process.h"
#include "lldb/Core/PluginManager.h"
using namespace lldb;
using namespace lldb_private;
SystemRuntime*
SystemRuntime::FindPlugin (Process *process)
{
SystemRuntimeCreateInstance create_callback = NULL;
for (uint32_t idx = 0; (create_callback = PluginManager::GetSystemRuntimeCreateCallbackAtIndex(idx)) != NULL; ++idx)
{
std::unique_ptr<SystemRuntime> instance_ap(create_callback(process));
if (instance_ap.get())
return instance_ap.release();
}
return NULL;
}
//----------------------------------------------------------------------
// SystemRuntime constructor
//----------------------------------------------------------------------
SystemRuntime::SystemRuntime(Process *process) :
m_process (process)
{
}
//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
SystemRuntime::~SystemRuntime()
{
}
void
SystemRuntime::DidAttach ()
{
}
void
SystemRuntime::DidLaunch()
{
}
void
SystemRuntime::ModulesDidLoad (ModuleList &module_list)
{
}
uint32_t
SystemRuntime::GetStatus (Stream &strm, ExecutionContext &exe_ctx)
{
return 0;
}

View File

@ -43,6 +43,7 @@
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/SystemRuntime.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadSpec.h"
@ -1155,6 +1156,14 @@ Target::ModulesDidLoad (ModuleList &module_list)
if (module_list.GetSize())
{
m_breakpoint_list.UpdateBreakpoints (module_list, true);
if (m_process_sp)
{
SystemRuntime *sys_runtime = m_process_sp->GetSystemRuntime();
if (sys_runtime)
{
sys_runtime->ModulesDidLoad (module_list);
}
}
// TODO: make event data that packages up the module_list
BroadcastEvent (eBroadcastBitModulesLoaded, NULL);
}