Index: lldb/bindings/interface/SBProcess.i =================================================================== --- lldb/bindings/interface/SBProcess.i +++ lldb/bindings/interface/SBProcess.i @@ -344,6 +344,11 @@ bool GetDescription (lldb::SBStream &description); + %feature("autodoc", " + Returns the implementation object of the process plugin if available. None otherwise.") GetImplementation; + ScriptedObject + GetImplementation(); + %feature("autodoc", " Returns the process' extended crash information.") GetExtendedCrashInformation; lldb::SBStructuredData Index: lldb/bindings/python/python-typemaps.swig =================================================================== --- lldb/bindings/python/python-typemaps.swig +++ lldb/bindings/python/python-typemaps.swig @@ -54,6 +54,18 @@ free((char *) $1); } +%typemap(out) lldb::ScriptedObject { + $result = nullptr; + const void* impl = $1; + if (impl) { + $result = (PyObject*) impl; + } + if (!$result) { + $result = Py_None; + Py_INCREF(Py_None); + } +} + %typemap(out) char** { int len; int i; Index: lldb/include/lldb/API/SBDefines.h =================================================================== --- lldb/include/lldb/API/SBDefines.h +++ lldb/include/lldb/API/SBDefines.h @@ -110,6 +110,7 @@ typedef bool (*SBBreakpointHitCallback)(void *baton, SBProcess &process, SBThread &thread, lldb::SBBreakpointLocation &location); +typedef void *ScriptedObject; } #endif // LLDB_API_SBDEFINES_H Index: lldb/include/lldb/API/SBProcess.h =================================================================== --- lldb/include/lldb/API/SBProcess.h +++ lldb/include/lldb/API/SBProcess.h @@ -423,6 +423,8 @@ /// lldb::SBError DeallocateMemory(lldb::addr_t ptr); + lldb::ScriptedObject GetImplementation(); + protected: friend class SBAddress; friend class SBBreakpoint; Index: lldb/include/lldb/Target/Process.h =================================================================== --- lldb/include/lldb/Target/Process.h +++ lldb/include/lldb/Target/Process.h @@ -2526,6 +2526,8 @@ lldb::StructuredDataPluginSP GetStructuredDataPlugin(ConstString type_name) const; + virtual void *GetImplementation() { return nullptr; } + protected: friend class Trace; Index: lldb/source/API/SBProcess.cpp =================================================================== --- lldb/source/API/SBProcess.cpp +++ lldb/source/API/SBProcess.cpp @@ -1262,3 +1262,9 @@ } return sb_error; } + +ScriptedObject SBProcess::GetImplementation() { + LLDB_INSTRUMENT_VA(this); + ProcessSP process_sp(GetSP()); + return (process_sp) ? process_sp->GetImplementation() : nullptr; +} Index: lldb/source/Plugins/Process/scripted/ScriptedProcess.h =================================================================== --- lldb/source/Plugins/Process/scripted/ScriptedProcess.h +++ lldb/source/Plugins/Process/scripted/ScriptedProcess.h @@ -74,6 +74,8 @@ void UpdateQueueListIfNeeded() override; + void *GetImplementation() override; + protected: ScriptedProcess(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, const ScriptedMetadata &scripted_metadata, Status &error); Index: lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp =================================================================== --- lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp +++ lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp @@ -512,3 +512,10 @@ ScriptedProcessInterface &ScriptedProcess::GetInterface() const { return m_interpreter->GetScriptedProcessInterface(); } + +void *ScriptedProcess::GetImplementation() { + if (m_script_object_sp && + m_script_object_sp->GetType() == eStructuredDataTypeGeneric) + return m_script_object_sp->GetAsGeneric()->GetValue(); + return nullptr; +} Index: lldb/test/API/functionalities/scripted_process/TestScriptedProcess.py =================================================================== --- lldb/test/API/functionalities/scripted_process/TestScriptedProcess.py +++ lldb/test/API/functionalities/scripted_process/TestScriptedProcess.py @@ -10,6 +10,8 @@ from lldbsuite.test import lldbutil from lldbsuite.test import lldbtest +import dummy_scripted_process + class ScriptedProcesTestCase(TestBase): NO_DEBUG_INFO_TESTCASE = True @@ -118,6 +120,14 @@ self.assertEqual(process.GetProcessID(), 42) self.assertEqual(process.GetNumThreads(), 1) + py_impl = process.GetImplementation() + self.assertTrue(py_impl) + self.assertTrue(isinstance(py_impl, dummy_scripted_process.DummyScriptedProcess)) + self.assertFalse(hasattr(py_impl, 'my_super_secret_member')) + py_impl.my_super_secret_member = 42 + self.assertTrue(hasattr(py_impl, 'my_super_secret_member')) + self.assertEqual(py_impl.my_super_secret_method(), 42) + addr = 0x500000000 message = "Hello, world!" buff = process.ReadCStringFromMemory(addr, len(message) + 1, error) Index: lldb/test/API/functionalities/scripted_process/dummy_scripted_process.py =================================================================== --- lldb/test/API/functionalities/scripted_process/dummy_scripted_process.py +++ lldb/test/API/functionalities/scripted_process/dummy_scripted_process.py @@ -43,6 +43,12 @@ def get_scripted_thread_plugin(self): return DummyScriptedThread.__module__ + "." + DummyScriptedThread.__name__ + def my_super_secret_method(self): + if hasattr(self, 'my_super_secret_member'): + return self.my_super_secret_member + else: + return None + class DummyScriptedThread(ScriptedThread): def __init__(self, process, args):