[Lldb-commits] [lldb] [lldb] Setup session when calling Python interfaces (PR #197966)
via lldb-commits
lldb-commits at lists.llvm.org
Sat May 16 04:11:40 PDT 2026
https://github.com/Nerixyz updated https://github.com/llvm/llvm-project/pull/197966
>From 34bd4e78f158441a906f157a0210a2cff5254302 Mon Sep 17 00:00:00 2001
From: Nerixyz <nerixdev at outlook.de>
Date: Fri, 15 May 2026 17:59:03 +0200
Subject: [PATCH 1/2] [lldb] Setup session when calling Python interfaces
---
.../Python/Interfaces/ScriptedPythonInterface.h | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h
index 637ca1b2ab1f9..921a8fe715198 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h
@@ -192,8 +192,9 @@ class ScriptedPythonInterface : virtual public ScriptedInterface {
return create_error("Missing scripting object.");
}
- Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN,
- Locker::FreeLock);
+ Locker py_lock(&m_interpreter,
+ Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN,
+ Locker::FreeLock | Locker::TearDownSession);
PythonObject result = {};
@@ -413,8 +414,9 @@ class ScriptedPythonInterface : virtual public ScriptedInterface {
return ErrorWithMessage<T>(caller_signature, "missing script class name",
error);
- Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN,
- Locker::FreeLock);
+ Locker py_lock(&m_interpreter,
+ Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN,
+ Locker::FreeLock | Locker::TearDownSession);
// Get the interpreter dictionary.
auto dict =
@@ -508,8 +510,9 @@ class ScriptedPythonInterface : virtual public ScriptedInterface {
return ErrorWithMessage<T>(caller_signature, "python object ill-formed",
error);
- Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN,
- Locker::FreeLock);
+ Locker py_lock(&m_interpreter,
+ Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN,
+ Locker::FreeLock | Locker::TearDownSession);
PythonObject implementor(PyRefType::Borrowed,
(PyObject *)m_object_instance_sp->GetValue());
>From 1c7588c36234a6cd6bd8b75499aa3fb77ef5eb91 Mon Sep 17 00:00:00 2001
From: Nerixyz <nerixdev at outlook.de>
Date: Fri, 15 May 2026 22:41:24 +0200
Subject: [PATCH 2/2] refactor: split stdio & globals
---
.../Interfaces/ScriptedPythonInterface.h | 12 ++---
.../Python/ScriptInterpreterPython.cpp | 54 +++++++++++--------
.../Python/ScriptInterpreterPythonImpl.h | 27 +++++++---
3 files changed, 59 insertions(+), 34 deletions(-)
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h
index 921a8fe715198..56ef1db630c34 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h
@@ -193,8 +193,8 @@ class ScriptedPythonInterface : virtual public ScriptedInterface {
}
Locker py_lock(&m_interpreter,
- Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN,
- Locker::FreeLock | Locker::TearDownSession);
+ Locker::AcquireLock | Locker::InitStdio | Locker::NoSTDIN,
+ Locker::FreeLock | Locker::TearDownStdio);
PythonObject result = {};
@@ -415,8 +415,8 @@ class ScriptedPythonInterface : virtual public ScriptedInterface {
error);
Locker py_lock(&m_interpreter,
- Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN,
- Locker::FreeLock | Locker::TearDownSession);
+ Locker::AcquireLock | Locker::InitStdio | Locker::NoSTDIN,
+ Locker::FreeLock | Locker::TearDownStdio);
// Get the interpreter dictionary.
auto dict =
@@ -511,8 +511,8 @@ class ScriptedPythonInterface : virtual public ScriptedInterface {
error);
Locker py_lock(&m_interpreter,
- Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN,
- Locker::FreeLock | Locker::TearDownSession);
+ Locker::AcquireLock | Locker::InitStdio | Locker::NoSTDIN,
+ Locker::FreeLock | Locker::TearDownStdio);
PythonObject implementor(PyRefType::Borrowed,
(PyObject *)m_object_instance_sp->GetValue());
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
index 3c002394d8760..daf1acd1e8707 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
@@ -322,14 +322,13 @@ void ScriptInterpreterPython::Terminate() {
ScriptInterpreterPythonImpl::Locker::Locker(
ScriptInterpreterPythonImpl *py_interpreter, uint16_t on_entry,
uint16_t on_leave, FileSP in, FileSP out, FileSP err)
- : ScriptInterpreterLocker(),
- m_teardown_session((on_leave & TearDownSession) == TearDownSession),
+ : ScriptInterpreterLocker(), m_on_leave(on_leave),
m_python_interpreter(py_interpreter) {
DoAcquireLock();
- if ((on_entry & InitSession) == InitSession) {
+ if (on_entry & InitSessionMask) {
if (!DoInitSession(on_entry, in, out, err)) {
// Don't teardown the session if we didn't init it.
- m_teardown_session = false;
+ m_on_leave &= ~TearDownSessionMask;
}
}
}
@@ -370,12 +369,13 @@ bool ScriptInterpreterPythonImpl::Locker::DoFreeLock() {
bool ScriptInterpreterPythonImpl::Locker::DoTearDownSession() {
if (!m_python_interpreter)
return false;
- m_python_interpreter->LeaveSession();
+ m_python_interpreter->LeaveSession(m_on_leave & TearDownGlobals,
+ m_on_leave & TearDownStdio);
return true;
}
ScriptInterpreterPythonImpl::Locker::~Locker() {
- if (m_teardown_session)
+ if (m_on_leave & TearDownSessionMask)
DoTearDownSession();
DoFreeLock();
}
@@ -550,21 +550,24 @@ ScriptInterpreterPythonImpl::CreateInstance(Debugger &debugger) {
return std::make_shared<ScriptInterpreterPythonImpl>(debugger);
}
-void ScriptInterpreterPythonImpl::LeaveSession() {
+void ScriptInterpreterPythonImpl::LeaveSession(bool clear_globals,
+ bool clear_stdio) {
Log *log = GetLog(LLDBLog::Script);
if (log)
log->PutCString("ScriptInterpreterPythonImpl::LeaveSession()");
- // Unset the LLDB global variables.
- RunSimpleString("lldb.debugger = None; lldb.target = None; lldb.process "
- "= None; lldb.thread = None; lldb.frame = None");
+ if (clear_globals) {
+ // Unset the LLDB global variables.
+ RunSimpleString("lldb.debugger = None; lldb.target = None; lldb.process "
+ "= None; lldb.thread = None; lldb.frame = None");
+ }
// checking that we have a valid thread state - since we use our own
// threading and locking in some (rare) cases during cleanup Python may end
// up believing we have no thread state and PyImport_AddModule will crash if
// that is the case - since that seems to only happen when destroying the
// SBDebugger, we can make do without clearing up stdout and stderr
- if (PyThreadState_GetDict()) {
+ if (clear_stdio && PyThreadState_GetDict()) {
PythonDictionary &sys_module_dict = GetSysModuleDictionary();
if (sys_module_dict.IsValid()) {
if (m_saved_stdin.IsValid()) {
@@ -639,6 +642,10 @@ bool ScriptInterpreterPythonImpl::EnterSession(uint16_t on_entry_flags,
StreamString run_string;
+ assert((on_entry_flags & (Locker::InitGlobals | Locker::InitDebugger)) !=
+ (Locker::InitGlobals | Locker::InitDebugger) &&
+ "InitGlobals and InitDebugger are mutually exclusive");
+
if (on_entry_flags & Locker::InitGlobals) {
run_string.Printf("run_one_line (%s, 'lldb.debugger_unique_id = %" PRIu64,
m_dictionary_name.c_str(), m_debugger.GetID());
@@ -650,7 +657,7 @@ bool ScriptInterpreterPythonImpl::EnterSession(uint16_t on_entry_flags,
run_string.PutCString("; lldb.thread = lldb.process.GetSelectedThread ()");
run_string.PutCString("; lldb.frame = lldb.thread.GetSelectedFrame ()");
run_string.PutCString("')");
- } else {
+ } else if (on_entry_flags & Locker::InitDebugger) {
// If we aren't initing the globals, we should still always set the
// debugger (since that is always unique.)
run_string.Printf("run_one_line (%s, 'lldb.debugger_unique_id = %" PRIu64,
@@ -661,11 +668,13 @@ bool ScriptInterpreterPythonImpl::EnterSession(uint16_t on_entry_flags,
run_string.PutCString("')");
}
- RunSimpleString(run_string.GetData());
- run_string.Clear();
+ if (!run_string.Empty()) {
+ RunSimpleString(run_string.GetData());
+ run_string.Clear();
+ }
PythonDictionary &sys_module_dict = GetSysModuleDictionary();
- if (sys_module_dict.IsValid()) {
+ if ((on_entry_flags & Locker::InitStdio) && sys_module_dict.IsValid()) {
lldb::FileSP top_in_sp;
lldb::LockableStreamFileSP top_out_sp, top_err_sp;
if (!in_sp || !out_sp || !err_sp || !*in_sp || !*out_sp || !*err_sp)
@@ -835,8 +844,9 @@ bool ScriptInterpreterPythonImpl::ExecuteOneLine(
// happen.
Locker locker(
this,
- Locker::AcquireLock | Locker::InitSession |
- (options.GetSetLLDBGlobals() ? Locker::InitGlobals : 0) |
+ Locker::AcquireLock | Locker::InitStdio |
+ (options.GetSetLLDBGlobals() ? Locker::InitGlobals
+ : Locker::InitDebugger) |
((result && result->GetInteractive()) ? 0 : Locker::NoSTDIN),
Locker::FreeAcquiredLock | Locker::TearDownSession,
io_redirect.GetInputFile(), io_redirect.GetOutputFile(),
@@ -962,8 +972,9 @@ bool ScriptInterpreterPythonImpl::ExecuteOneLineWithReturn(
ScriptInterpreterIORedirect &io_redirect = **io_redirect_or_error;
Locker locker(this,
- Locker::AcquireLock | Locker::InitSession |
- (options.GetSetLLDBGlobals() ? Locker::InitGlobals : 0) |
+ Locker::AcquireLock | Locker::InitStdio |
+ (options.GetSetLLDBGlobals() ? Locker::InitGlobals
+ : Locker::InitDebugger) |
Locker::NoSTDIN,
Locker::FreeAcquiredLock | Locker::TearDownSession,
io_redirect.GetInputFile(), io_redirect.GetOutputFile(),
@@ -1086,8 +1097,9 @@ Status ScriptInterpreterPythonImpl::ExecuteMultipleLines(
ScriptInterpreterIORedirect &io_redirect = **io_redirect_or_error;
Locker locker(this,
- Locker::AcquireLock | Locker::InitSession |
- (options.GetSetLLDBGlobals() ? Locker::InitGlobals : 0) |
+ Locker::AcquireLock | Locker::InitStdio |
+ (options.GetSetLLDBGlobals() ? Locker::InitGlobals
+ : Locker::InitDebugger) |
Locker::NoSTDIN,
Locker::FreeAcquiredLock | Locker::TearDownSession,
io_redirect.GetInputFile(), io_redirect.GetOutputFile(),
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
index 863cf27785824..e89cd6da62379 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
@@ -305,16 +305,29 @@ class ScriptInterpreterPythonImpl : public ScriptInterpreterPython {
public:
enum OnEntry {
AcquireLock = 0x0001,
- InitSession = 0x0002,
- InitGlobals = 0x0004,
- NoSTDIN = 0x0008
+ InitStdio = 0x0002,
+ /// Set lldb.debugger. Mutually exclusive with `InitGlobals`.
+ InitDebugger = 0x0004,
+ /// Set lldb.{debugger,target,process,thread,frame}. Mutually exclusive
+ /// with `InitDebugger`.
+ InitGlobals = 0x0008,
+ NoSTDIN = 0x0010,
+
+ InitSession = InitStdio | InitDebugger,
+
+ InitSessionMask = InitStdio | InitDebugger | InitGlobals,
};
enum OnLeave {
FreeLock = 0x0001,
FreeAcquiredLock = 0x0002, // do not free the lock if we already held it
// when calling constructor
- TearDownSession = 0x0004
+ TearDownGlobals = 0x0004,
+ TearDownStdio = 0x0008,
+
+ TearDownSession = TearDownGlobals | TearDownStdio,
+
+ TearDownSessionMask = TearDownGlobals | TearDownStdio,
};
Locker(ScriptInterpreterPythonImpl *py_interpreter,
@@ -335,7 +348,7 @@ class ScriptInterpreterPythonImpl : public ScriptInterpreterPython {
bool DoTearDownSession();
- bool m_teardown_session;
+ uint16_t m_on_leave;
ScriptInterpreterPythonImpl *m_python_interpreter;
PyGILState_STATE m_GILState;
};
@@ -368,7 +381,7 @@ class ScriptInterpreterPythonImpl : public ScriptInterpreterPython {
bool EnterSession(uint16_t on_entry_flags, lldb::FileSP in, lldb::FileSP out,
lldb::FileSP err);
- void LeaveSession();
+ void LeaveSession(bool clear_globals = true, bool reset_stdio = true);
uint32_t IsExecutingPython() {
std::lock_guard<std::mutex> guard(m_mutex);
@@ -457,7 +470,7 @@ class IOHandlerPythonInterpreter : public IOHandler {
ScriptInterpreterPythonImpl::Locker locker(
m_python,
ScriptInterpreterPythonImpl::Locker::AcquireLock |
- ScriptInterpreterPythonImpl::Locker::InitSession |
+ ScriptInterpreterPythonImpl::Locker::InitStdio |
ScriptInterpreterPythonImpl::Locker::InitGlobals,
ScriptInterpreterPythonImpl::Locker::FreeAcquiredLock |
ScriptInterpreterPythonImpl::Locker::TearDownSession);
More information about the lldb-commits
mailing list