mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-25 10:48:14 +00:00
<rdar://problem/12491420>
Added a new setting that allows a python OS plug-in to detect threads and provide registers for memory threads. To enable this you set the setting: settings set target.process.python-os-plugin-path lldb/examples/python/operating_system.py Then run your program and see the extra threads. llvm-svn: 166244
This commit is contained in:
parent
ed8560b09c
commit
c9d645d306
@ -3,7 +3,7 @@
|
||||
import lldb
|
||||
import struct
|
||||
|
||||
class PlugIn(object):
|
||||
class OperatingSystemPlugIn(object):
|
||||
"""Class that provides data for an instance of a LLDB 'OperatingSystemPython' plug-in class"""
|
||||
|
||||
def __init__(self, process):
|
||||
|
@ -127,19 +127,28 @@ public:
|
||||
virtual ~ScriptInterpreter ();
|
||||
|
||||
virtual bool
|
||||
ExecuteOneLine (const char *command, CommandReturnObject *result, bool enable_io) = 0;
|
||||
ExecuteOneLine (const char *command,
|
||||
CommandReturnObject *result,
|
||||
bool enable_io,
|
||||
bool set_lldb_globals = true) = 0;
|
||||
|
||||
virtual void
|
||||
ExecuteInterpreterLoop () = 0;
|
||||
|
||||
virtual bool
|
||||
ExecuteOneLineWithReturn (const char *in_string, ScriptReturnType return_type, void *ret_value, bool enable_io)
|
||||
ExecuteOneLineWithReturn (const char *in_string,
|
||||
ScriptReturnType return_type,
|
||||
void *ret_value,
|
||||
bool enable_io,
|
||||
bool set_lldb_globals = true)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool
|
||||
ExecuteMultipleLines (const char *in_string, bool enable_io)
|
||||
ExecuteMultipleLines (const char *in_string,
|
||||
bool enable_io,
|
||||
bool set_lldb_globals = true)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@ -308,6 +317,7 @@ public:
|
||||
virtual bool
|
||||
LoadScriptingModule (const char* filename,
|
||||
bool can_reload,
|
||||
bool init_session,
|
||||
lldb_private::Error& error)
|
||||
{
|
||||
error.SetErrorString("loading unimplemented");
|
||||
|
@ -23,7 +23,7 @@ public:
|
||||
~ScriptInterpreterNone ();
|
||||
|
||||
bool
|
||||
ExecuteOneLine (const char *command, CommandReturnObject *result, bool enable_io);
|
||||
ExecuteOneLine (const char *command, CommandReturnObject *result, bool enable_io, bool set_lldb_globals = true);
|
||||
|
||||
void
|
||||
ExecuteInterpreterLoop ();
|
||||
|
@ -39,7 +39,10 @@ public:
|
||||
~ScriptInterpreterPython ();
|
||||
|
||||
bool
|
||||
ExecuteOneLine (const char *command, CommandReturnObject *result, bool enable_io);
|
||||
ExecuteOneLine (const char *command,
|
||||
CommandReturnObject *result,
|
||||
bool enable_io,
|
||||
bool set_lldb_globals = true);
|
||||
|
||||
void
|
||||
ExecuteInterpreterLoop ();
|
||||
@ -48,10 +51,13 @@ public:
|
||||
ExecuteOneLineWithReturn (const char *in_string,
|
||||
ScriptInterpreter::ScriptReturnType return_type,
|
||||
void *ret_value,
|
||||
bool enable_io);
|
||||
bool enable_io,
|
||||
bool set_lldb_globals = true);
|
||||
|
||||
bool
|
||||
ExecuteMultipleLines (const char *in_string, bool enable_io);
|
||||
ExecuteMultipleLines (const char *in_string,
|
||||
bool enable_io,
|
||||
bool set_lldb_globals = true);
|
||||
|
||||
bool
|
||||
ExportFunctionDefinitionToInterpreter (StringList &function_def);
|
||||
@ -155,6 +161,7 @@ public:
|
||||
virtual bool
|
||||
LoadScriptingModule (const char* filename,
|
||||
bool can_reload,
|
||||
bool init_session,
|
||||
lldb_private::Error& error);
|
||||
|
||||
virtual lldb::ScriptInterpreterObjectSP
|
||||
|
@ -67,6 +67,12 @@ public:
|
||||
|
||||
void
|
||||
SetExtraStartupCommands (const Args &args);
|
||||
|
||||
FileSpec
|
||||
GetPythonOSPluginPath () const;
|
||||
|
||||
void
|
||||
SetPythonOSPluginPath (const FileSpec &file);
|
||||
};
|
||||
|
||||
typedef STD_SHARED_PTR(ProcessProperties) ProcessPropertiesSP;
|
||||
|
@ -1394,8 +1394,10 @@ protected:
|
||||
std::string path = command.GetArgumentAtIndex(0);
|
||||
Error error;
|
||||
|
||||
const bool init_session = true;
|
||||
if (m_interpreter.GetScriptInterpreter()->LoadScriptingModule(path.c_str(),
|
||||
m_options.m_allow_reload,
|
||||
init_session,
|
||||
error))
|
||||
{
|
||||
result.SetStatus (eReturnStatusSuccessFinishNoResult);
|
||||
|
@ -26,7 +26,7 @@ ScriptInterpreterNone::~ScriptInterpreterNone ()
|
||||
}
|
||||
|
||||
bool
|
||||
ScriptInterpreterNone::ExecuteOneLine (const char *command, CommandReturnObject *, bool enable_io)
|
||||
ScriptInterpreterNone::ExecuteOneLine (const char *command, CommandReturnObject *, bool enable_io, bool set_lldb_globals)
|
||||
{
|
||||
m_interpreter.GetDebugger().GetErrorStream().PutCString ("error: there is no embedded script interpreter in this mode.\n");
|
||||
return false;
|
||||
|
@ -721,7 +721,7 @@ GenerateUniqueName (const char* base_name_wanted,
|
||||
}
|
||||
|
||||
bool
|
||||
ScriptInterpreterPython::ExecuteOneLine (const char *command, CommandReturnObject *result, bool enable_io)
|
||||
ScriptInterpreterPython::ExecuteOneLine (const char *command, CommandReturnObject *result, bool enable_io, bool set_lldb_globals)
|
||||
{
|
||||
if (!m_valid_session)
|
||||
return false;
|
||||
@ -732,8 +732,8 @@ ScriptInterpreterPython::ExecuteOneLine (const char *command, CommandReturnObjec
|
||||
// method to pass the command string directly down to Python.
|
||||
|
||||
Locker locker(this,
|
||||
ScriptInterpreterPython::Locker::AcquireLock | ScriptInterpreterPython::Locker::InitSession,
|
||||
ScriptInterpreterPython::Locker::FreeAcquiredLock | ScriptInterpreterPython::Locker::TearDownSession);
|
||||
ScriptInterpreterPython::Locker::AcquireLock | (set_lldb_globals ? ScriptInterpreterPython::Locker::InitSession : 0),
|
||||
ScriptInterpreterPython::Locker::FreeAcquiredLock | (set_lldb_globals ? ScriptInterpreterPython::Locker::TearDownSession : 0));
|
||||
|
||||
bool success = false;
|
||||
|
||||
@ -1000,12 +1000,13 @@ bool
|
||||
ScriptInterpreterPython::ExecuteOneLineWithReturn (const char *in_string,
|
||||
ScriptInterpreter::ScriptReturnType return_type,
|
||||
void *ret_value,
|
||||
bool enable_io)
|
||||
bool enable_io,
|
||||
bool set_lldb_globals)
|
||||
{
|
||||
|
||||
Locker locker(this,
|
||||
ScriptInterpreterPython::Locker::AcquireLock | ScriptInterpreterPython::Locker::InitSession,
|
||||
ScriptInterpreterPython::Locker::FreeAcquiredLock | ScriptInterpreterPython::Locker::TearDownSession);
|
||||
ScriptInterpreterPython::Locker::AcquireLock | (set_lldb_globals ? ScriptInterpreterPython::Locker::InitSession : 0),
|
||||
ScriptInterpreterPython::Locker::FreeAcquiredLock | (set_lldb_globals ? ScriptInterpreterPython::Locker::TearDownSession : 0));
|
||||
|
||||
PyObject *py_return = NULL;
|
||||
PyObject *mainmod = PyImport_AddModule ("__main__");
|
||||
@ -1165,13 +1166,13 @@ ScriptInterpreterPython::ExecuteOneLineWithReturn (const char *in_string,
|
||||
}
|
||||
|
||||
bool
|
||||
ScriptInterpreterPython::ExecuteMultipleLines (const char *in_string, bool enable_io)
|
||||
ScriptInterpreterPython::ExecuteMultipleLines (const char *in_string, bool enable_io, bool set_lldb_globals)
|
||||
{
|
||||
|
||||
|
||||
Locker locker(this,
|
||||
ScriptInterpreterPython::Locker::AcquireLock | ScriptInterpreterPython::Locker::InitSession,
|
||||
ScriptInterpreterPython::Locker::FreeAcquiredLock | ScriptInterpreterPython::Locker::TearDownSession);
|
||||
ScriptInterpreterPython::Locker::AcquireLock | (set_lldb_globals ? ScriptInterpreterPython::Locker::InitSession : 0),
|
||||
ScriptInterpreterPython::Locker::FreeAcquiredLock | (set_lldb_globals ? ScriptInterpreterPython::Locker::TearDownSession : 0));
|
||||
|
||||
bool success = false;
|
||||
PyObject *py_return = NULL;
|
||||
@ -2373,6 +2374,7 @@ ScriptInterpreterPython::UpdateSynthProviderInstance (const lldb::ScriptInterpre
|
||||
bool
|
||||
ScriptInterpreterPython::LoadScriptingModule (const char* pathname,
|
||||
bool can_reload,
|
||||
bool init_lldb_globals,
|
||||
lldb_private::Error& error)
|
||||
{
|
||||
if (!pathname || !pathname[0])
|
||||
@ -2404,14 +2406,16 @@ ScriptInterpreterPython::LoadScriptingModule (const char* pathname,
|
||||
std::string basename(target_file.GetFilename().GetCString());
|
||||
|
||||
// Before executing Pyton code, lock the GIL.
|
||||
Locker py_lock(this);
|
||||
Locker py_lock (this,
|
||||
Locker::AcquireLock | (init_lldb_globals ? Locker::InitSession : 0),
|
||||
Locker::FreeAcquiredLock | (init_lldb_globals ? Locker::TearDownSession : 0));
|
||||
|
||||
// now make sure that Python has "directory" in the search path
|
||||
StreamString command_stream;
|
||||
command_stream.Printf("if not (sys.path.__contains__('%s')):\n sys.path.append('%s');\n\n",
|
||||
directory,
|
||||
directory);
|
||||
bool syspath_retval = ExecuteMultipleLines(command_stream.GetData(), false);
|
||||
bool syspath_retval = ExecuteMultipleLines(command_stream.GetData(), false, false);
|
||||
if (!syspath_retval)
|
||||
{
|
||||
error.SetErrorString("Python sys.path handling failed");
|
||||
@ -2432,7 +2436,10 @@ ScriptInterpreterPython::LoadScriptingModule (const char* pathname,
|
||||
// this call will fail if the module does not exist (because the parameter to it is not a string
|
||||
// but an actual Python module object, which is non-existant if the module was not imported before)
|
||||
bool was_imported = (ExecuteOneLineWithReturn(command_stream.GetData(),
|
||||
ScriptInterpreterPython::eScriptReturnTypeInt, &refcount, false) && refcount > 0);
|
||||
ScriptInterpreterPython::eScriptReturnTypeInt,
|
||||
&refcount,
|
||||
false,
|
||||
false) && refcount > 0);
|
||||
if (was_imported == true && can_reload == false)
|
||||
{
|
||||
error.SetErrorString("module already imported");
|
||||
@ -2442,7 +2449,7 @@ ScriptInterpreterPython::LoadScriptingModule (const char* pathname,
|
||||
// now actually do the import
|
||||
command_stream.Clear();
|
||||
command_stream.Printf("import %s",basename.c_str());
|
||||
bool import_retval = ExecuteOneLine(command_stream.GetData(), NULL, false);
|
||||
bool import_retval = ExecuteOneLine(command_stream.GetData(), NULL, false, false);
|
||||
if (!import_retval)
|
||||
{
|
||||
error.SetErrorString("Python import statement failed");
|
||||
|
@ -55,8 +55,13 @@ OperatingSystem *
|
||||
OperatingSystemPython::CreateInstance (Process *process, bool force)
|
||||
{
|
||||
// Python OperatingSystem plug-ins must be requested by name, so force must be true
|
||||
if (force)
|
||||
return new OperatingSystemPython (process);
|
||||
FileSpec python_os_plugin_spec (process->GetPythonOSPluginPath());
|
||||
if (python_os_plugin_spec && python_os_plugin_spec.Exists())
|
||||
{
|
||||
std::auto_ptr<OperatingSystemPython> os_ap (new OperatingSystemPython (process, python_os_plugin_spec));
|
||||
if (os_ap.get() && os_ap->IsValid())
|
||||
return os_ap.release();
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -74,12 +79,12 @@ OperatingSystemPython::GetPluginDescriptionStatic()
|
||||
}
|
||||
|
||||
|
||||
OperatingSystemPython::OperatingSystemPython (lldb_private::Process *process) :
|
||||
OperatingSystemPython::OperatingSystemPython (lldb_private::Process *process, const FileSpec &python_module_path) :
|
||||
OperatingSystem (process),
|
||||
m_thread_list_valobj_sp (),
|
||||
m_register_info_ap (),
|
||||
m_interpreter(NULL),
|
||||
m_python_object(NULL)
|
||||
m_interpreter (NULL),
|
||||
m_python_object (NULL)
|
||||
{
|
||||
if (!process)
|
||||
return;
|
||||
@ -89,13 +94,27 @@ OperatingSystemPython::OperatingSystemPython (lldb_private::Process *process) :
|
||||
m_interpreter = target_sp->GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
|
||||
if (m_interpreter)
|
||||
{
|
||||
// TODO: hardcoded is not good
|
||||
auto object_sp = m_interpreter->CreateOSPlugin("operating_system.PlugIn",process->CalculateProcess());
|
||||
if (object_sp)
|
||||
|
||||
std::string os_plugin_class_name (python_module_path.GetFilename().AsCString(""));
|
||||
if (!os_plugin_class_name.empty())
|
||||
{
|
||||
m_python_object = object_sp->GetObject();
|
||||
|
||||
//GetDynamicRegisterInfo (); // COMMENT THIS LINE OUT PRIOR TO CHECKIN!!!
|
||||
const bool init_session = false;
|
||||
const bool allow_reload = true;
|
||||
char python_module_path_cstr[PATH_MAX];
|
||||
python_module_path.GetPath(python_module_path_cstr, sizeof(python_module_path_cstr));
|
||||
Error error;
|
||||
if (m_interpreter->LoadScriptingModule (python_module_path_cstr, allow_reload, init_session, error))
|
||||
{
|
||||
// Strip the ".py" extension if there is one
|
||||
size_t py_extension_pos = os_plugin_class_name.rfind(".py");
|
||||
if (py_extension_pos != std::string::npos)
|
||||
os_plugin_class_name.erase (py_extension_pos);
|
||||
// Add ".OperatingSystemPlugIn" to the module name to get a string like "modulename.OperatingSystemPlugIn"
|
||||
os_plugin_class_name += ".OperatingSystemPlugIn";
|
||||
auto object_sp = m_interpreter->CreateOSPlugin(os_plugin_class_name.c_str(), process->CalculateProcess());
|
||||
if (object_sp)
|
||||
m_python_object = object_sp->GetObject();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -217,8 +236,8 @@ OperatingSystemPython::CreateRegisterContextForThread (Thread *thread)
|
||||
return RegisterContextSP();
|
||||
auto object_sp = m_interpreter->OSPlugin_QueryForRegisterContextData (m_interpreter->MakeScriptObject(m_python_object),
|
||||
thread->GetID());
|
||||
|
||||
if (!object_sp)
|
||||
|
||||
if (!object_sp)
|
||||
return RegisterContextSP();
|
||||
|
||||
PythonDataString reg_context_data((PyObject*)object_sp->GetObject());
|
||||
|
@ -43,7 +43,8 @@ public:
|
||||
//------------------------------------------------------------------
|
||||
// Class Methods
|
||||
//------------------------------------------------------------------
|
||||
OperatingSystemPython (lldb_private::Process *process);
|
||||
OperatingSystemPython (lldb_private::Process *process,
|
||||
const lldb_private::FileSpec &python_module_path);
|
||||
|
||||
virtual
|
||||
~OperatingSystemPython ();
|
||||
@ -78,6 +79,10 @@ public:
|
||||
|
||||
protected:
|
||||
|
||||
bool IsValid() const
|
||||
{
|
||||
return m_python_object != NULL;
|
||||
}
|
||||
DynamicRegisterInfo *
|
||||
GetDynamicRegisterInfo ();
|
||||
|
||||
|
@ -94,12 +94,14 @@ g_properties[] =
|
||||
{
|
||||
{ "disable-memory-cache" , OptionValue::eTypeBoolean, false, DISABLE_MEM_CACHE_DEFAULT, NULL, NULL, "Disable reading and caching of memory in fixed-size units." },
|
||||
{ "extra-startup-command", OptionValue::eTypeArray , false, OptionValue::eTypeString, NULL, NULL, "A list containing extra commands understood by the particular process plugin used." },
|
||||
{ "python-os-plugin-path", OptionValue::eTypeFileSpec, false, 0, NULL, NULL, "A path to a python OS plug-in module file that contains a OperatingSystemPlugIn class." },
|
||||
{ NULL , OptionValue::eTypeInvalid, false, 0, NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
enum {
|
||||
ePropertyDisableMemCache,
|
||||
ePropertyExtraStartCommand
|
||||
ePropertyExtraStartCommand,
|
||||
ePropertyPythonOSPluginPath
|
||||
};
|
||||
|
||||
ProcessProperties::ProcessProperties (bool is_global) :
|
||||
@ -145,6 +147,20 @@ ProcessProperties::SetExtraStartupCommands (const Args &args)
|
||||
m_collection_sp->SetPropertyAtIndexFromArgs(NULL, idx, args);
|
||||
}
|
||||
|
||||
FileSpec
|
||||
ProcessProperties::GetPythonOSPluginPath () const
|
||||
{
|
||||
const uint32_t idx = ePropertyPythonOSPluginPath;
|
||||
return m_collection_sp->GetPropertyAtIndexAsFileSpec(NULL, idx);
|
||||
}
|
||||
|
||||
void
|
||||
ProcessProperties::SetPythonOSPluginPath (const FileSpec &file)
|
||||
{
|
||||
const uint32_t idx = ePropertyPythonOSPluginPath;
|
||||
m_collection_sp->SetPropertyAtIndexAsFileSpec(NULL, idx, file);
|
||||
}
|
||||
|
||||
void
|
||||
ProcessInstanceInfo::Dump (Stream &s, Platform *platform) const
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user