Skip to content

Commit fc34a10

Browse files
committed
[lldb] Add a way to get a scripted process implementation from the SBAPI
This patch introduces a new `GetScriptedImplementation` method to the SBProcess class in the SBAPI. It will allow users of Scripted Processes to fetch the scripted implementation object from to script interpreter to be able to interact with it directly (without having to go through lldb). This allows to user to perform action that are not specified in the scripted process interface, like calling un-specified methods, but also to enrich the implementation, by passing it complex objects. Differential Revision: https://reviews.llvm.org/D143236 Signed-off-by: Med Ismail Bennani <[email protected]>
1 parent 5a337ea commit fc34a10

File tree

11 files changed

+64
-0
lines changed

11 files changed

+64
-0
lines changed

lldb/bindings/interface/SBProcess.i

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,12 @@ public:
344344
bool
345345
GetDescription (lldb::SBStream &description);
346346

347+
%feature("autodoc", "
348+
Returns the implementation object of the process plugin if available. None
349+
otherwise.") GetScriptedImplementation;
350+
ScriptedObject
351+
GetScriptedImplementation();
352+
347353
%feature("autodoc", "
348354
Returns the process' extended crash information.") GetExtendedCrashInformation;
349355
lldb::SBStructuredData

lldb/bindings/python/python-typemaps.swig

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,16 @@
5454
free((char *) $1);
5555
}
5656

57+
%typemap(out) lldb::ScriptedObject {
58+
$result = nullptr;
59+
if (const void* impl = $1)
60+
$result = (PyObject*) impl;
61+
if (!$result) {
62+
$result = Py_None;
63+
Py_INCREF(Py_None);
64+
}
65+
}
66+
5767
%typemap(out) char** {
5868
int len;
5969
int i;

lldb/include/lldb/API/SBDefines.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ class LLDB_API SBUnixSignals;
110110
typedef bool (*SBBreakpointHitCallback)(void *baton, SBProcess &process,
111111
SBThread &thread,
112112
lldb::SBBreakpointLocation &location);
113+
typedef void *ScriptedObject;
113114
}
114115

115116
#endif // LLDB_API_SBDEFINES_H

lldb/include/lldb/API/SBProcess.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,8 @@ class LLDB_API SBProcess {
423423
///
424424
lldb::SBError DeallocateMemory(lldb::addr_t ptr);
425425

426+
lldb::ScriptedObject GetScriptedImplementation();
427+
426428
protected:
427429
friend class SBAddress;
428430
friend class SBBreakpoint;

lldb/include/lldb/Target/Process.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2561,6 +2561,8 @@ void PruneThreadPlans();
25612561
lldb::StructuredDataPluginSP
25622562
GetStructuredDataPlugin(ConstString type_name) const;
25632563

2564+
virtual void *GetImplementation() { return nullptr; }
2565+
25642566
protected:
25652567
friend class Trace;
25662568

lldb/source/API/SBProcess.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1262,3 +1262,9 @@ lldb::SBError SBProcess::DeallocateMemory(lldb::addr_t ptr) {
12621262
}
12631263
return sb_error;
12641264
}
1265+
1266+
ScriptedObject SBProcess::GetScriptedImplementation() {
1267+
LLDB_INSTRUMENT_VA(this);
1268+
ProcessSP process_sp(GetSP());
1269+
return (process_sp) ? process_sp->GetImplementation() : nullptr;
1270+
}

lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -512,3 +512,10 @@ void ScriptedProcess::UpdateQueueListIfNeeded() {
512512
ScriptedProcessInterface &ScriptedProcess::GetInterface() const {
513513
return m_interpreter->GetScriptedProcessInterface();
514514
}
515+
516+
void *ScriptedProcess::GetImplementation() {
517+
if (m_script_object_sp &&
518+
m_script_object_sp->GetType() == eStructuredDataTypeGeneric)
519+
return m_script_object_sp->GetAsGeneric()->GetValue();
520+
return nullptr;
521+
}

lldb/source/Plugins/Process/scripted/ScriptedProcess.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ class ScriptedProcess : public Process {
7474

7575
void UpdateQueueListIfNeeded() override;
7676

77+
void *GetImplementation() override;
78+
7779
protected:
7880
ScriptedProcess(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp,
7981
const ScriptedMetadata &scripted_metadata, Status &error);

lldb/test/API/functionalities/scripted_process/TestScriptedProcess.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
from lldbsuite.test import lldbutil
1111
from lldbsuite.test import lldbtest
1212

13+
import dummy_scripted_process
14+
1315
class ScriptedProcesTestCase(TestBase):
1416

1517
NO_DEBUG_INFO_TESTCASE = True
@@ -123,6 +125,14 @@ def cleanup():
123125
self.assertEqual(process.GetProcessID(), 42)
124126
self.assertEqual(process.GetNumThreads(), 1)
125127

128+
py_impl = process.GetScriptedImplementation()
129+
self.assertTrue(py_impl)
130+
self.assertTrue(isinstance(py_impl, dummy_scripted_process.DummyScriptedProcess))
131+
self.assertFalse(hasattr(py_impl, 'my_super_secret_member'))
132+
py_impl.my_super_secret_member = 42
133+
self.assertTrue(hasattr(py_impl, 'my_super_secret_member'))
134+
self.assertEqual(py_impl.my_super_secret_method(), 42)
135+
126136
addr = 0x500000000
127137
message = "Hello, world!"
128138
buff = process.ReadCStringFromMemory(addr, len(message) + 1, error)

lldb/test/API/functionalities/scripted_process/dummy_scripted_process.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,12 @@ def is_alive(self) -> bool:
4343
def get_scripted_thread_plugin(self):
4444
return DummyScriptedThread.__module__ + "." + DummyScriptedThread.__name__
4545

46+
def my_super_secret_method(self):
47+
if hasattr(self, 'my_super_secret_member'):
48+
return self.my_super_secret_member
49+
else:
50+
return None
51+
4652

4753
class DummyScriptedThread(ScriptedThread):
4854
def __init__(self, process, args):

0 commit comments

Comments
 (0)