Bug Summary

File:build/source/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
Warning:line 109, column 7
Value stored to 'ReadlinePatched' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name ScriptInterpreterPython.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/build/source/build-llvm/tools/clang/stage2-bins -resource-dir /usr/lib/llvm-17/lib/clang/17 -isystem /usr/include/libxml2 -D HAVE_ROUND -D LLDB_PYTHON_EXE_RELATIVE_PATH="bin/python3.9" -D LLDB_PYTHON_RELATIVE_LIBDIR="lib/python3/dist-packages" -D _DEBUG -D _GLIBCXX_ASSERTIONS -D _GNU_SOURCE -D _LIBCPP_ENABLE_ASSERTIONS -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I tools/lldb/source/Plugins/ScriptInterpreter/Python -I /build/source/lldb/source/Plugins/ScriptInterpreter/Python -I /build/source/lldb/include -I tools/lldb/include -I include -I /build/source/llvm/include -I /usr/include/python3.9 -I /build/source/clang/include -I tools/lldb/../clang/include -I /build/source/lldb/source -I tools/lldb/source -D _FORTIFY_SOURCE=2 -D NDEBUG -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/x86_64-linux-gnu/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/backward -internal-isystem /usr/lib/llvm-17/lib/clang/17/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/build/source/build-llvm/tools/clang/stage2-bins=build-llvm/tools/clang/stage2-bins -fmacro-prefix-map=/build/source/= -fcoverage-prefix-map=/build/source/build-llvm/tools/clang/stage2-bins=build-llvm/tools/clang/stage2-bins -fcoverage-prefix-map=/build/source/= -source-date-epoch 1683717183 -O2 -Wno-unused-command-line-argument -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-class-memaccess -Wno-redundant-move -Wno-pessimizing-move -Wno-noexcept-type -Wno-comment -Wno-misleading-indentation -Wno-deprecated-declarations -Wno-unknown-pragmas -Wno-strict-aliasing -Wno-stringop-truncation -std=c++17 -fdeprecated-macro -fdebug-compilation-dir=/build/source/build-llvm/tools/clang/stage2-bins -fdebug-prefix-map=/build/source/build-llvm/tools/clang/stage2-bins=build-llvm/tools/clang/stage2-bins -fdebug-prefix-map=/build/source/= -ferror-limit 19 -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcolor-diagnostics -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2023-05-10-133810-16478-1 -x c++ /build/source/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
1//===-- ScriptInterpreterPython.cpp ---------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "lldb/Host/Config.h"
10#include "lldb/lldb-enumerations.h"
11
12#if LLDB_ENABLE_PYTHON1
13
14// LLDB Python header must be included first
15#include "lldb-python.h"
16
17#include "PythonDataObjects.h"
18#include "PythonReadline.h"
19#include "SWIGPythonBridge.h"
20#include "ScriptInterpreterPythonImpl.h"
21#include "ScriptedPlatformPythonInterface.h"
22#include "ScriptedProcessPythonInterface.h"
23
24#include "lldb/API/SBError.h"
25#include "lldb/API/SBFrame.h"
26#include "lldb/API/SBValue.h"
27#include "lldb/Breakpoint/StoppointCallbackContext.h"
28#include "lldb/Breakpoint/WatchpointOptions.h"
29#include "lldb/Core/Debugger.h"
30#include "lldb/Core/PluginManager.h"
31#include "lldb/Core/ThreadedCommunication.h"
32#include "lldb/Core/ValueObject.h"
33#include "lldb/DataFormatters/TypeSummary.h"
34#include "lldb/Host/FileSystem.h"
35#include "lldb/Host/HostInfo.h"
36#include "lldb/Host/Pipe.h"
37#include "lldb/Interpreter/CommandInterpreter.h"
38#include "lldb/Interpreter/CommandReturnObject.h"
39#include "lldb/Target/Thread.h"
40#include "lldb/Target/ThreadPlan.h"
41#include "lldb/Utility/Instrumentation.h"
42#include "lldb/Utility/LLDBLog.h"
43#include "lldb/Utility/Timer.h"
44#include "llvm/ADT/STLExtras.h"
45#include "llvm/ADT/StringRef.h"
46#include "llvm/Support/Error.h"
47#include "llvm/Support/FileSystem.h"
48#include "llvm/Support/FormatAdapters.h"
49
50#include <cstdio>
51#include <cstdlib>
52#include <memory>
53#include <mutex>
54#include <optional>
55#include <string>
56
57using namespace lldb;
58using namespace lldb_private;
59using namespace lldb_private::python;
60using llvm::Expected;
61
62LLDB_PLUGIN_DEFINE(ScriptInterpreterPython)namespace lldb_private { void lldb_initialize_ScriptInterpreterPython
() { ScriptInterpreterPython::Initialize(); } void lldb_terminate_ScriptInterpreterPython
() { ScriptInterpreterPython::Terminate(); } }
63
64// Defined in the SWIG source file
65extern "C" PyObject *PyInit__lldb(void);
66
67#define LLDBSwigPyInitPyInit__lldb PyInit__lldb
68
69#if defined(_WIN32)
70// Don't mess with the signal handlers on Windows.
71#define LLDB_USE_PYTHON_SET_INTERRUPT(3 == 3 && 9 >= 2) || (3 > 3) 0
72#else
73// PyErr_SetInterrupt was introduced in 3.2.
74#define LLDB_USE_PYTHON_SET_INTERRUPT(3 == 3 && 9 >= 2) || (3 > 3) \
75 (PY_MAJOR_VERSION3 == 3 && PY_MINOR_VERSION9 >= 2) || (PY_MAJOR_VERSION3 > 3)
76#endif
77
78static ScriptInterpreterPythonImpl *GetPythonInterpreter(Debugger &debugger) {
79 ScriptInterpreter *script_interpreter =
80 debugger.GetScriptInterpreter(true, lldb::eScriptLanguagePython);
81 return static_cast<ScriptInterpreterPythonImpl *>(script_interpreter);
82}
83
84namespace {
85
86// Initializing Python is not a straightforward process. We cannot control
87// what external code may have done before getting to this point in LLDB,
88// including potentially having already initialized Python, so we need to do a
89// lot of work to ensure that the existing state of the system is maintained
90// across our initialization. We do this by using an RAII pattern where we
91// save off initial state at the beginning, and restore it at the end
92struct InitializePythonRAII {
93public:
94 InitializePythonRAII() {
95 InitializePythonHome();
96
97#ifdef LLDB_USE_LIBEDIT_READLINE_COMPAT_MODULE1
98 // Python's readline is incompatible with libedit being linked into lldb.
99 // Provide a patched version local to the embedded interpreter.
100 bool ReadlinePatched = false;
101 for (auto *p = PyImport_Inittab; p->name != nullptr; p++) {
102 if (strcmp(p->name, "readline") == 0) {
103 p->initfunc = initlldb_readline;
104 break;
105 }
106 }
107 if (!ReadlinePatched) {
108 PyImport_AppendInittab("readline", initlldb_readline);
109 ReadlinePatched = true;
Value stored to 'ReadlinePatched' is never read
110 }
111#endif
112
113 // Register _lldb as a built-in module.
114 PyImport_AppendInittab("_lldb", LLDBSwigPyInitPyInit__lldb);
115
116// Python < 3.2 and Python >= 3.2 reversed the ordering requirements for
117// calling `Py_Initialize` and `PyEval_InitThreads`. < 3.2 requires that you
118// call `PyEval_InitThreads` first, and >= 3.2 requires that you call it last.
119#if (PY_MAJOR_VERSION3 == 3 && PY_MINOR_VERSION9 >= 2) || (PY_MAJOR_VERSION3 > 3)
120 Py_InitializeEx(0);
121 InitializeThreadsPrivate();
122#else
123 InitializeThreadsPrivate();
124 Py_InitializeEx(0);
125#endif
126 }
127
128 ~InitializePythonRAII() {
129 if (m_was_already_initialized) {
130 Log *log = GetLog(LLDBLog::Script);
131 LLDB_LOGV(log, "Releasing PyGILState. Returning to state = {0}locked",do { ::lldb_private::Log *log_private = (log); if (log_private
&& log_private->GetVerbose()) log_private->Format
("lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp"
, __func__, "Releasing PyGILState. Returning to state = {0}locked"
, m_gil_state == PyGILState_UNLOCKED ? "un" : ""); } while (0
)
132 m_gil_state == PyGILState_UNLOCKED ? "un" : "")do { ::lldb_private::Log *log_private = (log); if (log_private
&& log_private->GetVerbose()) log_private->Format
("lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp"
, __func__, "Releasing PyGILState. Returning to state = {0}locked"
, m_gil_state == PyGILState_UNLOCKED ? "un" : ""); } while (0
)
;
133 PyGILState_Release(m_gil_state);
134 } else {
135 // We initialized the threads in this function, just unlock the GIL.
136 PyEval_SaveThread();
137 }
138 }
139
140private:
141 void InitializePythonHome() {
142#if LLDB_EMBED_PYTHON_HOME0
143 typedef wchar_t *str_type;
144 static str_type g_python_home = []() -> str_type {
145 const char *lldb_python_home = LLDB_PYTHON_HOME;
146 const char *absolute_python_home = nullptr;
147 llvm::SmallString<64> path;
148 if (llvm::sys::path::is_absolute(lldb_python_home)) {
149 absolute_python_home = lldb_python_home;
150 } else {
151 FileSpec spec = HostInfo::GetShlibDir();
152 if (!spec)
153 return nullptr;
154 spec.GetPath(path);
155 llvm::sys::path::append(path, lldb_python_home);
156 absolute_python_home = path.c_str();
157 }
158 size_t size = 0;
159 return Py_DecodeLocale(absolute_python_home, &size);
160 }();
161 if (g_python_home != nullptr) {
162 Py_SetPythonHome(g_python_home);
163 }
164#endif
165 }
166
167 void InitializeThreadsPrivate() {
168// Since Python 3.7 `Py_Initialize` calls `PyEval_InitThreads` inside itself,
169// so there is no way to determine whether the embedded interpreter
170// was already initialized by some external code. `PyEval_ThreadsInitialized`
171// would always return `true` and `PyGILState_Ensure/Release` flow would be
172// executed instead of unlocking GIL with `PyEval_SaveThread`. When
173// an another thread calls `PyGILState_Ensure` it would get stuck in deadlock.
174#if (PY_MAJOR_VERSION3 == 3 && PY_MINOR_VERSION9 >= 7) || (PY_MAJOR_VERSION3 > 3)
175 // The only case we should go further and acquire the GIL: it is unlocked.
176 if (PyGILState_Check())
177 return;
178#endif
179
180 if (PyEval_ThreadsInitialized()) {
181 Log *log = GetLog(LLDBLog::Script);
182
183 m_was_already_initialized = true;
184 m_gil_state = PyGILState_Ensure();
185 LLDB_LOGV(log, "Ensured PyGILState. Previous state = {0}locked\n",do { ::lldb_private::Log *log_private = (log); if (log_private
&& log_private->GetVerbose()) log_private->Format
("lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp"
, __func__, "Ensured PyGILState. Previous state = {0}locked\n"
, m_gil_state == PyGILState_UNLOCKED ? "un" : ""); } while (0
)
186 m_gil_state == PyGILState_UNLOCKED ? "un" : "")do { ::lldb_private::Log *log_private = (log); if (log_private
&& log_private->GetVerbose()) log_private->Format
("lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp"
, __func__, "Ensured PyGILState. Previous state = {0}locked\n"
, m_gil_state == PyGILState_UNLOCKED ? "un" : ""); } while (0
)
;
187 return;
188 }
189
190 // InitThreads acquires the GIL if it hasn't been called before.
191 PyEval_InitThreads();
192 }
193
194 PyGILState_STATE m_gil_state = PyGILState_UNLOCKED;
195 bool m_was_already_initialized = false;
196};
197
198#if LLDB_USE_PYTHON_SET_INTERRUPT(3 == 3 && 9 >= 2) || (3 > 3)
199/// Saves the current signal handler for the specified signal and restores
200/// it at the end of the current scope.
201struct RestoreSignalHandlerScope {
202 /// The signal handler.
203 struct sigaction m_prev_handler;
204 int m_signal_code;
205 RestoreSignalHandlerScope(int signal_code) : m_signal_code(signal_code) {
206 // Initialize sigaction to their default state.
207 std::memset(&m_prev_handler, 0, sizeof(m_prev_handler));
208 // Don't install a new handler, just read back the old one.
209 struct sigaction *new_handler = nullptr;
210 int signal_err = ::sigaction(m_signal_code, new_handler, &m_prev_handler);
211 lldbassert(signal_err == 0 && "sigaction failed to read handler")lldb_private::lldb_assert(static_cast<bool>(signal_err ==
0 && "sigaction failed to read handler"), "signal_err == 0 && \"sigaction failed to read handler\""
, __FUNCTION__, "lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp"
, 211)
;
212 }
213 ~RestoreSignalHandlerScope() {
214 int signal_err = ::sigaction(m_signal_code, &m_prev_handler, nullptr);
215 lldbassert(signal_err == 0 && "sigaction failed to restore old handler")lldb_private::lldb_assert(static_cast<bool>(signal_err ==
0 && "sigaction failed to restore old handler"), "signal_err == 0 && \"sigaction failed to restore old handler\""
, __FUNCTION__, "lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp"
, 215)
;
216 }
217};
218#endif
219} // namespace
220
221void ScriptInterpreterPython::ComputePythonDirForApple(
222 llvm::SmallVectorImpl<char> &path) {
223 auto style = llvm::sys::path::Style::posix;
224
225 llvm::StringRef path_ref(path.begin(), path.size());
226 auto rbegin = llvm::sys::path::rbegin(path_ref, style);
227 auto rend = llvm::sys::path::rend(path_ref);
228 auto framework = std::find(rbegin, rend, "LLDB.framework");
229 if (framework == rend) {
230 ComputePythonDir(path);
231 return;
232 }
233 path.resize(framework - rend);
234 llvm::sys::path::append(path, style, "LLDB.framework", "Resources", "Python");
235}
236
237void ScriptInterpreterPython::ComputePythonDir(
238 llvm::SmallVectorImpl<char> &path) {
239 // Build the path by backing out of the lib dir, then building with whatever
240 // the real python interpreter uses. (e.g. lib for most, lib64 on RHEL
241 // x86_64, or bin on Windows).
242 llvm::sys::path::remove_filename(path);
243 llvm::sys::path::append(path, "/llvm-" + std::to_string(LLVM_VERSION_MAJOR17));
244 llvm::sys::path::append(path, LLDB_PYTHON_RELATIVE_LIBDIR"lib/python3/dist-packages");
245
246#if defined(_WIN32)
247 // This will be injected directly through FileSpec.SetDirectory(),
248 // so we need to normalize manually.
249 std::replace(path.begin(), path.end(), '\\', '/');
250#endif
251}
252
253FileSpec ScriptInterpreterPython::GetPythonDir() {
254 static FileSpec g_spec = []() {
255 FileSpec spec = HostInfo::GetShlibDir();
256 if (!spec)
257 return FileSpec();
258 llvm::SmallString<64> path;
259 spec.GetPath(path);
260
261#if defined(__APPLE__)
262 ComputePythonDirForApple(path);
263#else
264 ComputePythonDir(path);
265#endif
266 spec.SetDirectory(path);
267 return spec;
268 }();
269 return g_spec;
270}
271
272static const char GetInterpreterInfoScript[] = R"(
273import os
274import sys
275
276def main(lldb_python_dir, python_exe_relative_path):
277 info = {
278 "lldb-pythonpath": lldb_python_dir,
279 "language": "python",
280 "prefix": sys.prefix,
281 "executable": os.path.join(sys.prefix, python_exe_relative_path)
282 }
283 return info
284)";
285
286static const char python_exe_relative_path[] = LLDB_PYTHON_EXE_RELATIVE_PATH"bin/python3.9";
287
288StructuredData::DictionarySP ScriptInterpreterPython::GetInterpreterInfo() {
289 GIL gil;
290 FileSpec python_dir_spec = GetPythonDir();
291 if (!python_dir_spec)
292 return nullptr;
293 PythonScript get_info(GetInterpreterInfoScript);
294 auto info_json = unwrapIgnoringErrors(
295 As<PythonDictionary>(get_info(PythonString(python_dir_spec.GetPath()),
296 PythonString(python_exe_relative_path))));
297 if (!info_json)
298 return nullptr;
299 return info_json.CreateStructuredDictionary();
300}
301
302void ScriptInterpreterPython::SharedLibraryDirectoryHelper(
303 FileSpec &this_file) {
304 // When we're loaded from python, this_file will point to the file inside the
305 // python package directory. Replace it with the one in the lib directory.
306#ifdef _WIN32
307 // On windows, we need to manually back out of the python tree, and go into
308 // the bin directory. This is pretty much the inverse of what ComputePythonDir
309 // does.
310 if (this_file.GetFileNameExtension() == ".pyd") {
311 this_file.RemoveLastPathComponent(); // _lldb.pyd or _lldb_d.pyd
312 this_file.RemoveLastPathComponent(); // lldb
313 llvm::StringRef libdir = LLDB_PYTHON_RELATIVE_LIBDIR"lib/python3/dist-packages";
314 for (auto it = llvm::sys::path::begin(libdir),
315 end = llvm::sys::path::end(libdir);
316 it != end; ++it)
317 this_file.RemoveLastPathComponent();
318 this_file.AppendPathComponent("bin");
319 this_file.AppendPathComponent("liblldb.dll");
320 }
321#else
322 // The python file is a symlink, so we can find the real library by resolving
323 // it. We can do this unconditionally.
324 FileSystem::Instance().ResolveSymbolicLink(this_file, this_file);
325#endif
326}
327
328llvm::StringRef ScriptInterpreterPython::GetPluginDescriptionStatic() {
329 return "Embedded Python interpreter";
330}
331
332void ScriptInterpreterPython::Initialize() {
333 static llvm::once_flag g_once_flag;
334 llvm::call_once(g_once_flag, []() {
335 PluginManager::RegisterPlugin(GetPluginNameStatic(),
336 GetPluginDescriptionStatic(),
337 lldb::eScriptLanguagePython,
338 ScriptInterpreterPythonImpl::CreateInstance);
339 ScriptInterpreterPythonImpl::Initialize();
340 });
341}
342
343void ScriptInterpreterPython::Terminate() {}
344
345ScriptInterpreterPythonImpl::Locker::Locker(
346 ScriptInterpreterPythonImpl *py_interpreter, uint16_t on_entry,
347 uint16_t on_leave, FileSP in, FileSP out, FileSP err)
348 : ScriptInterpreterLocker(),
349 m_teardown_session((on_leave & TearDownSession) == TearDownSession),
350 m_python_interpreter(py_interpreter) {
351 DoAcquireLock();
352 if ((on_entry & InitSession) == InitSession) {
353 if (!DoInitSession(on_entry, in, out, err)) {
354 // Don't teardown the session if we didn't init it.
355 m_teardown_session = false;
356 }
357 }
358}
359
360bool ScriptInterpreterPythonImpl::Locker::DoAcquireLock() {
361 Log *log = GetLog(LLDBLog::Script);
362 m_GILState = PyGILState_Ensure();
363 LLDB_LOGV(log, "Ensured PyGILState. Previous state = {0}locked",do { ::lldb_private::Log *log_private = (log); if (log_private
&& log_private->GetVerbose()) log_private->Format
("lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp"
, __func__, "Ensured PyGILState. Previous state = {0}locked",
m_GILState == PyGILState_UNLOCKED ? "un" : ""); } while (0)
364 m_GILState == PyGILState_UNLOCKED ? "un" : "")do { ::lldb_private::Log *log_private = (log); if (log_private
&& log_private->GetVerbose()) log_private->Format
("lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp"
, __func__, "Ensured PyGILState. Previous state = {0}locked",
m_GILState == PyGILState_UNLOCKED ? "un" : ""); } while (0)
;
365
366 // we need to save the thread state when we first start the command because
367 // we might decide to interrupt it while some action is taking place outside
368 // of Python (e.g. printing to screen, waiting for the network, ...) in that
369 // case, _PyThreadState_Current will be NULL - and we would be unable to set
370 // the asynchronous exception - not a desirable situation
371 m_python_interpreter->SetThreadState(PyThreadState_Get());
372 m_python_interpreter->IncrementLockCount();
373 return true;
374}
375
376bool ScriptInterpreterPythonImpl::Locker::DoInitSession(uint16_t on_entry_flags,
377 FileSP in, FileSP out,
378 FileSP err) {
379 if (!m_python_interpreter)
380 return false;
381 return m_python_interpreter->EnterSession(on_entry_flags, in, out, err);
382}
383
384bool ScriptInterpreterPythonImpl::Locker::DoFreeLock() {
385 Log *log = GetLog(LLDBLog::Script);
386 LLDB_LOGV(log, "Releasing PyGILState. Returning to state = {0}locked",do { ::lldb_private::Log *log_private = (log); if (log_private
&& log_private->GetVerbose()) log_private->Format
("lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp"
, __func__, "Releasing PyGILState. Returning to state = {0}locked"
, m_GILState == PyGILState_UNLOCKED ? "un" : ""); } while (0)
387 m_GILState == PyGILState_UNLOCKED ? "un" : "")do { ::lldb_private::Log *log_private = (log); if (log_private
&& log_private->GetVerbose()) log_private->Format
("lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp"
, __func__, "Releasing PyGILState. Returning to state = {0}locked"
, m_GILState == PyGILState_UNLOCKED ? "un" : ""); } while (0)
;
388 PyGILState_Release(m_GILState);
389 m_python_interpreter->DecrementLockCount();
390 return true;
391}
392
393bool ScriptInterpreterPythonImpl::Locker::DoTearDownSession() {
394 if (!m_python_interpreter)
395 return false;
396 m_python_interpreter->LeaveSession();
397 return true;
398}
399
400ScriptInterpreterPythonImpl::Locker::~Locker() {
401 if (m_teardown_session)
402 DoTearDownSession();
403 DoFreeLock();
404}
405
406ScriptInterpreterPythonImpl::ScriptInterpreterPythonImpl(Debugger &debugger)
407 : ScriptInterpreterPython(debugger), m_saved_stdin(), m_saved_stdout(),
408 m_saved_stderr(), m_main_module(),
409 m_session_dict(PyInitialValue::Invalid),
410 m_sys_module_dict(PyInitialValue::Invalid), m_run_one_line_function(),
411 m_run_one_line_str_global(),
412 m_dictionary_name(m_debugger.GetInstanceName().AsCString()),
413 m_active_io_handler(eIOHandlerNone), m_session_is_active(false),
414 m_pty_secondary_is_open(false), m_valid_session(true), m_lock_count(0),
415 m_command_thread_state(nullptr) {
416 m_scripted_platform_interface_up =
417 std::make_unique<ScriptedPlatformPythonInterface>(*this);
418
419 m_dictionary_name.append("_dict");
420 StreamString run_string;
421 run_string.Printf("%s = dict()", m_dictionary_name.c_str());
422
423 Locker locker(this, Locker::AcquireLock, Locker::FreeAcquiredLock);
424 PyRun_SimpleString(run_string.GetData())PyRun_SimpleStringFlags(run_string.GetData(), __null);
425
426 run_string.Clear();
427 run_string.Printf(
428 "run_one_line (%s, 'import copy, keyword, os, re, sys, uuid, lldb')",
429 m_dictionary_name.c_str());
430 PyRun_SimpleString(run_string.GetData())PyRun_SimpleStringFlags(run_string.GetData(), __null);
431
432 // Reloading modules requires a different syntax in Python 2 and Python 3.
433 // This provides a consistent syntax no matter what version of Python.
434 run_string.Clear();
435 run_string.Printf("run_one_line (%s, 'from importlib import reload as reload_module')",
436 m_dictionary_name.c_str());
437 PyRun_SimpleString(run_string.GetData())PyRun_SimpleStringFlags(run_string.GetData(), __null);
438
439 // WARNING: temporary code that loads Cocoa formatters - this should be done
440 // on a per-platform basis rather than loading the whole set and letting the
441 // individual formatter classes exploit APIs to check whether they can/cannot
442 // do their task
443 run_string.Clear();
444 run_string.Printf(
445 "run_one_line (%s, 'import lldb.formatters, lldb.formatters.cpp')",
446 m_dictionary_name.c_str());
447 PyRun_SimpleString(run_string.GetData())PyRun_SimpleStringFlags(run_string.GetData(), __null);
448 run_string.Clear();
449
450 run_string.Printf("run_one_line (%s, 'import lldb.embedded_interpreter; from "
451 "lldb.embedded_interpreter import run_python_interpreter; "
452 "from lldb.embedded_interpreter import run_one_line')",
453 m_dictionary_name.c_str());
454 PyRun_SimpleString(run_string.GetData())PyRun_SimpleStringFlags(run_string.GetData(), __null);
455 run_string.Clear();
456
457 run_string.Printf("run_one_line (%s, 'lldb.debugger_unique_id = %" PRIu64"l" "u"
458 "')",
459 m_dictionary_name.c_str(), m_debugger.GetID());
460 PyRun_SimpleString(run_string.GetData())PyRun_SimpleStringFlags(run_string.GetData(), __null);
461}
462
463ScriptInterpreterPythonImpl::~ScriptInterpreterPythonImpl() {
464 // the session dictionary may hold objects with complex state which means
465 // that they may need to be torn down with some level of smarts and that, in
466 // turn, requires a valid thread state force Python to procure itself such a
467 // thread state, nuke the session dictionary and then release it for others
468 // to use and proceed with the rest of the shutdown
469 auto gil_state = PyGILState_Ensure();
470 m_session_dict.Reset();
471 PyGILState_Release(gil_state);
472}
473
474void ScriptInterpreterPythonImpl::IOHandlerActivated(IOHandler &io_handler,
475 bool interactive) {
476 const char *instructions = nullptr;
477
478 switch (m_active_io_handler) {
479 case eIOHandlerNone:
480 break;
481 case eIOHandlerBreakpoint:
482 instructions = R"(Enter your Python command(s). Type 'DONE' to end.
483def function (frame, bp_loc, internal_dict):
484 """frame: the lldb.SBFrame for the location at which you stopped
485 bp_loc: an lldb.SBBreakpointLocation for the breakpoint location information
486 internal_dict: an LLDB support object not to be used"""
487)";
488 break;
489 case eIOHandlerWatchpoint:
490 instructions = "Enter your Python command(s). Type 'DONE' to end.\n";
491 break;
492 }
493
494 if (instructions) {
495 StreamFileSP output_sp(io_handler.GetOutputStreamFileSP());
496 if (output_sp && interactive) {
497 output_sp->PutCString(instructions);
498 output_sp->Flush();
499 }
500 }
501}
502
503void ScriptInterpreterPythonImpl::IOHandlerInputComplete(IOHandler &io_handler,
504 std::string &data) {
505 io_handler.SetIsDone(true);
506 bool batch_mode = m_debugger.GetCommandInterpreter().GetBatchCommandMode();
507
508 switch (m_active_io_handler) {
509 case eIOHandlerNone:
510 break;
511 case eIOHandlerBreakpoint: {
512 std::vector<std::reference_wrapper<BreakpointOptions>> *bp_options_vec =
513 (std::vector<std::reference_wrapper<BreakpointOptions>> *)
514 io_handler.GetUserData();
515 for (BreakpointOptions &bp_options : *bp_options_vec) {
516
517 auto data_up = std::make_unique<CommandDataPython>();
518 if (!data_up)
519 break;
520 data_up->user_source.SplitIntoLines(data);
521
522 StructuredData::ObjectSP empty_args_sp;
523 if (GenerateBreakpointCommandCallbackData(data_up->user_source,
524 data_up->script_source,
525 /*has_extra_args=*/false,
526 /*is_callback=*/false)
527 .Success()) {
528 auto baton_sp = std::make_shared<BreakpointOptions::CommandBaton>(
529 std::move(data_up));
530 bp_options.SetCallback(
531 ScriptInterpreterPythonImpl::BreakpointCallbackFunction, baton_sp);
532 } else if (!batch_mode) {
533 StreamFileSP error_sp = io_handler.GetErrorStreamFileSP();
534 if (error_sp) {
535 error_sp->Printf("Warning: No command attached to breakpoint.\n");
536 error_sp->Flush();
537 }
538 }
539 }
540 m_active_io_handler = eIOHandlerNone;
541 } break;
542 case eIOHandlerWatchpoint: {
543 WatchpointOptions *wp_options =
544 (WatchpointOptions *)io_handler.GetUserData();
545 auto data_up = std::make_unique<WatchpointOptions::CommandData>();
546 data_up->user_source.SplitIntoLines(data);
547
548 if (GenerateWatchpointCommandCallbackData(data_up->user_source,
549 data_up->script_source,
550 /*is_callback=*/false)) {
551 auto baton_sp =
552 std::make_shared<WatchpointOptions::CommandBaton>(std::move(data_up));
553 wp_options->SetCallback(
554 ScriptInterpreterPythonImpl::WatchpointCallbackFunction, baton_sp);
555 } else if (!batch_mode) {
556 StreamFileSP error_sp = io_handler.GetErrorStreamFileSP();
557 if (error_sp) {
558 error_sp->Printf("Warning: No command attached to breakpoint.\n");
559 error_sp->Flush();
560 }
561 }
562 m_active_io_handler = eIOHandlerNone;
563 } break;
564 }
565}
566
567lldb::ScriptInterpreterSP
568ScriptInterpreterPythonImpl::CreateInstance(Debugger &debugger) {
569 return std::make_shared<ScriptInterpreterPythonImpl>(debugger);
570}
571
572void ScriptInterpreterPythonImpl::LeaveSession() {
573 Log *log = GetLog(LLDBLog::Script);
574 if (log)
575 log->PutCString("ScriptInterpreterPythonImpl::LeaveSession()");
576
577 // Unset the LLDB global variables.
578 PyRun_SimpleString("lldb.debugger = None; lldb.target = None; lldb.process "PyRun_SimpleStringFlags("lldb.debugger = None; lldb.target = None; lldb.process "
"= None; lldb.thread = None; lldb.frame = None", __null)
579 "= None; lldb.thread = None; lldb.frame = None")PyRun_SimpleStringFlags("lldb.debugger = None; lldb.target = None; lldb.process "
"= None; lldb.thread = None; lldb.frame = None", __null)
;
580
581 // checking that we have a valid thread state - since we use our own
582 // threading and locking in some (rare) cases during cleanup Python may end
583 // up believing we have no thread state and PyImport_AddModule will crash if
584 // that is the case - since that seems to only happen when destroying the
585 // SBDebugger, we can make do without clearing up stdout and stderr
586
587 // rdar://problem/11292882
588 // When the current thread state is NULL, PyThreadState_Get() issues a fatal
589 // error.
590 if (PyThreadState_GetDict()) {
591 PythonDictionary &sys_module_dict = GetSysModuleDictionary();
592 if (sys_module_dict.IsValid()) {
593 if (m_saved_stdin.IsValid()) {
594 sys_module_dict.SetItemForKey(PythonString("stdin"), m_saved_stdin);
595 m_saved_stdin.Reset();
596 }
597 if (m_saved_stdout.IsValid()) {
598 sys_module_dict.SetItemForKey(PythonString("stdout"), m_saved_stdout);
599 m_saved_stdout.Reset();
600 }
601 if (m_saved_stderr.IsValid()) {
602 sys_module_dict.SetItemForKey(PythonString("stderr"), m_saved_stderr);
603 m_saved_stderr.Reset();
604 }
605 }
606 }
607
608 m_session_is_active = false;
609}
610
611bool ScriptInterpreterPythonImpl::SetStdHandle(FileSP file_sp,
612 const char *py_name,
613 PythonObject &save_file,
614 const char *mode) {
615 if (!file_sp || !*file_sp) {
616 save_file.Reset();
617 return false;
618 }
619 File &file = *file_sp;
620
621 // Flush the file before giving it to python to avoid interleaved output.
622 file.Flush();
623
624 PythonDictionary &sys_module_dict = GetSysModuleDictionary();
625
626 auto new_file = PythonFile::FromFile(file, mode);
627 if (!new_file) {
628 llvm::consumeError(new_file.takeError());
629 return false;
630 }
631
632 save_file = sys_module_dict.GetItemForKey(PythonString(py_name));
633
634 sys_module_dict.SetItemForKey(PythonString(py_name), new_file.get());
635 return true;
636}
637
638bool ScriptInterpreterPythonImpl::EnterSession(uint16_t on_entry_flags,
639 FileSP in_sp, FileSP out_sp,
640 FileSP err_sp) {
641 // If we have already entered the session, without having officially 'left'
642 // it, then there is no need to 'enter' it again.
643 Log *log = GetLog(LLDBLog::Script);
644 if (m_session_is_active) {
645 LLDB_LOGF(do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Printf("ScriptInterpreterPythonImpl::EnterSession(on_entry_flags=0x%"
"x" ") session is already active, returning without doing anything"
, on_entry_flags); } while (0)
646 log,do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Printf("ScriptInterpreterPythonImpl::EnterSession(on_entry_flags=0x%"
"x" ") session is already active, returning without doing anything"
, on_entry_flags); } while (0)
647 "ScriptInterpreterPythonImpl::EnterSession(on_entry_flags=0x%" PRIx16do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Printf("ScriptInterpreterPythonImpl::EnterSession(on_entry_flags=0x%"
"x" ") session is already active, returning without doing anything"
, on_entry_flags); } while (0)
648 ") session is already active, returning without doing anything",do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Printf("ScriptInterpreterPythonImpl::EnterSession(on_entry_flags=0x%"
"x" ") session is already active, returning without doing anything"
, on_entry_flags); } while (0)
649 on_entry_flags)do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Printf("ScriptInterpreterPythonImpl::EnterSession(on_entry_flags=0x%"
"x" ") session is already active, returning without doing anything"
, on_entry_flags); } while (0)
;
650 return false;
651 }
652
653 LLDB_LOGF(do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Printf("ScriptInterpreterPythonImpl::EnterSession(on_entry_flags=0x%"
"x" ")", on_entry_flags); } while (0)
654 log,do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Printf("ScriptInterpreterPythonImpl::EnterSession(on_entry_flags=0x%"
"x" ")", on_entry_flags); } while (0)
655 "ScriptInterpreterPythonImpl::EnterSession(on_entry_flags=0x%" PRIx16 ")",do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Printf("ScriptInterpreterPythonImpl::EnterSession(on_entry_flags=0x%"
"x" ")", on_entry_flags); } while (0)
656 on_entry_flags)do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Printf("ScriptInterpreterPythonImpl::EnterSession(on_entry_flags=0x%"
"x" ")", on_entry_flags); } while (0)
;
657
658 m_session_is_active = true;
659
660 StreamString run_string;
661
662 if (on_entry_flags & Locker::InitGlobals) {
663 run_string.Printf("run_one_line (%s, 'lldb.debugger_unique_id = %" PRIu64"l" "u",
664 m_dictionary_name.c_str(), m_debugger.GetID());
665 run_string.Printf(
666 "; lldb.debugger = lldb.SBDebugger.FindDebuggerWithID (%" PRIu64"l" "u" ")",
667 m_debugger.GetID());
668 run_string.PutCString("; lldb.target = lldb.debugger.GetSelectedTarget()");
669 run_string.PutCString("; lldb.process = lldb.target.GetProcess()");
670 run_string.PutCString("; lldb.thread = lldb.process.GetSelectedThread ()");
671 run_string.PutCString("; lldb.frame = lldb.thread.GetSelectedFrame ()");
672 run_string.PutCString("')");
673 } else {
674 // If we aren't initing the globals, we should still always set the
675 // debugger (since that is always unique.)
676 run_string.Printf("run_one_line (%s, 'lldb.debugger_unique_id = %" PRIu64"l" "u",
677 m_dictionary_name.c_str(), m_debugger.GetID());
678 run_string.Printf(
679 "; lldb.debugger = lldb.SBDebugger.FindDebuggerWithID (%" PRIu64"l" "u" ")",
680 m_debugger.GetID());
681 run_string.PutCString("')");
682 }
683
684 PyRun_SimpleString(run_string.GetData())PyRun_SimpleStringFlags(run_string.GetData(), __null);
685 run_string.Clear();
686
687 PythonDictionary &sys_module_dict = GetSysModuleDictionary();
688 if (sys_module_dict.IsValid()) {
689 lldb::FileSP top_in_sp;
690 lldb::StreamFileSP top_out_sp, top_err_sp;
691 if (!in_sp || !out_sp || !err_sp || !*in_sp || !*out_sp || !*err_sp)
692 m_debugger.AdoptTopIOHandlerFilesIfInvalid(top_in_sp, top_out_sp,
693 top_err_sp);
694
695 if (on_entry_flags & Locker::NoSTDIN) {
696 m_saved_stdin.Reset();
697 } else {
698 if (!SetStdHandle(in_sp, "stdin", m_saved_stdin, "r")) {
699 if (top_in_sp)
700 SetStdHandle(top_in_sp, "stdin", m_saved_stdin, "r");
701 }
702 }
703
704 if (!SetStdHandle(out_sp, "stdout", m_saved_stdout, "w")) {
705 if (top_out_sp)
706 SetStdHandle(top_out_sp->GetFileSP(), "stdout", m_saved_stdout, "w");
707 }
708
709 if (!SetStdHandle(err_sp, "stderr", m_saved_stderr, "w")) {
710 if (top_err_sp)
711 SetStdHandle(top_err_sp->GetFileSP(), "stderr", m_saved_stderr, "w");
712 }
713 }
714
715 if (PyErr_Occurred())
716 PyErr_Clear();
717
718 return true;
719}
720
721PythonModule &ScriptInterpreterPythonImpl::GetMainModule() {
722 if (!m_main_module.IsValid())
723 m_main_module = unwrapIgnoringErrors(PythonModule::Import("__main__"));
724 return m_main_module;
725}
726
727PythonDictionary &ScriptInterpreterPythonImpl::GetSessionDictionary() {
728 if (m_session_dict.IsValid())
729 return m_session_dict;
730
731 PythonObject &main_module = GetMainModule();
732 if (!main_module.IsValid())
733 return m_session_dict;
734
735 PythonDictionary main_dict(PyRefType::Borrowed,
736 PyModule_GetDict(main_module.get()));
737 if (!main_dict.IsValid())
738 return m_session_dict;
739
740 m_session_dict = unwrapIgnoringErrors(
741 As<PythonDictionary>(main_dict.GetItem(m_dictionary_name)));
742 return m_session_dict;
743}
744
745PythonDictionary &ScriptInterpreterPythonImpl::GetSysModuleDictionary() {
746 if (m_sys_module_dict.IsValid())
747 return m_sys_module_dict;
748 PythonModule sys_module = unwrapIgnoringErrors(PythonModule::Import("sys"));
749 m_sys_module_dict = sys_module.GetDictionary();
750 return m_sys_module_dict;
751}
752
753llvm::Expected<unsigned>
754ScriptInterpreterPythonImpl::GetMaxPositionalArgumentsForCallable(
755 const llvm::StringRef &callable_name) {
756 if (callable_name.empty()) {
757 return llvm::createStringError(
758 llvm::inconvertibleErrorCode(),
759 "called with empty callable name.");
760 }
761 Locker py_lock(this, Locker::AcquireLock |
762 Locker::InitSession |
763 Locker::NoSTDIN);
764 auto dict = PythonModule::MainModule()
765 .ResolveName<PythonDictionary>(m_dictionary_name);
766 auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
767 callable_name, dict);
768 if (!pfunc.IsAllocated()) {
769 return llvm::createStringError(
770 llvm::inconvertibleErrorCode(),
771 "can't find callable: %s", callable_name.str().c_str());
772 }
773 llvm::Expected<PythonCallable::ArgInfo> arg_info = pfunc.GetArgInfo();
774 if (!arg_info)
775 return arg_info.takeError();
776 return arg_info.get().max_positional_args;
777}
778
779static std::string GenerateUniqueName(const char *base_name_wanted,
780 uint32_t &functions_counter,
781 const void *name_token = nullptr) {
782 StreamString sstr;
783
784 if (!base_name_wanted)
785 return std::string();
786
787 if (!name_token)
788 sstr.Printf("%s_%d", base_name_wanted, functions_counter++);
789 else
790 sstr.Printf("%s_%p", base_name_wanted, name_token);
791
792 return std::string(sstr.GetString());
793}
794
795bool ScriptInterpreterPythonImpl::GetEmbeddedInterpreterModuleObjects() {
796 if (m_run_one_line_function.IsValid())
797 return true;
798
799 PythonObject module(PyRefType::Borrowed,
800 PyImport_AddModule("lldb.embedded_interpreter"));
801 if (!module.IsValid())
802 return false;
803
804 PythonDictionary module_dict(PyRefType::Borrowed,
805 PyModule_GetDict(module.get()));
806 if (!module_dict.IsValid())
807 return false;
808
809 m_run_one_line_function =
810 module_dict.GetItemForKey(PythonString("run_one_line"));
811 m_run_one_line_str_global =
812 module_dict.GetItemForKey(PythonString("g_run_one_line_str"));
813 return m_run_one_line_function.IsValid();
814}
815
816bool ScriptInterpreterPythonImpl::ExecuteOneLine(
817 llvm::StringRef command, CommandReturnObject *result,
818 const ExecuteScriptOptions &options) {
819 std::string command_str = command.str();
820
821 if (!m_valid_session)
822 return false;
823
824 if (!command.empty()) {
825 // We want to call run_one_line, passing in the dictionary and the command
826 // string. We cannot do this through PyRun_SimpleString here because the
827 // command string may contain escaped characters, and putting it inside
828 // another string to pass to PyRun_SimpleString messes up the escaping. So
829 // we use the following more complicated method to pass the command string
830 // directly down to Python.
831 llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>>
832 io_redirect_or_error = ScriptInterpreterIORedirect::Create(
833 options.GetEnableIO(), m_debugger, result);
834 if (!io_redirect_or_error) {
835 if (result)
836 result->AppendErrorWithFormatv(
837 "failed to redirect I/O: {0}\n",
838 llvm::fmt_consume(io_redirect_or_error.takeError()));
839 else
840 llvm::consumeError(io_redirect_or_error.takeError());
841 return false;
842 }
843
844 ScriptInterpreterIORedirect &io_redirect = **io_redirect_or_error;
845
846 bool success = false;
847 {
848 // WARNING! It's imperative that this RAII scope be as tight as
849 // possible. In particular, the scope must end *before* we try to join
850 // the read thread. The reason for this is that a pre-requisite for
851 // joining the read thread is that we close the write handle (to break
852 // the pipe and cause it to wake up and exit). But acquiring the GIL as
853 // below will redirect Python's stdio to use this same handle. If we
854 // close the handle while Python is still using it, bad things will
855 // happen.
856 Locker locker(
857 this,
858 Locker::AcquireLock | Locker::InitSession |
859 (options.GetSetLLDBGlobals() ? Locker::InitGlobals : 0) |
860 ((result && result->GetInteractive()) ? 0 : Locker::NoSTDIN),
861 Locker::FreeAcquiredLock | Locker::TearDownSession,
862 io_redirect.GetInputFile(), io_redirect.GetOutputFile(),
863 io_redirect.GetErrorFile());
864
865 // Find the correct script interpreter dictionary in the main module.
866 PythonDictionary &session_dict = GetSessionDictionary();
867 if (session_dict.IsValid()) {
868 if (GetEmbeddedInterpreterModuleObjects()) {
869 if (PyCallable_Check(m_run_one_line_function.get())) {
870 PythonObject pargs(
871 PyRefType::Owned,
872 Py_BuildValue("(Os)", session_dict.get(), command_str.c_str()));
873 if (pargs.IsValid()) {
874 PythonObject return_value(
875 PyRefType::Owned,
876 PyObject_CallObject(m_run_one_line_function.get(),
877 pargs.get()));
878 if (return_value.IsValid())
879 success = true;
880 else if (options.GetMaskoutErrors() && PyErr_Occurred()) {
881 PyErr_Print();
882 PyErr_Clear();
883 }
884 }
885 }
886 }
887 }
888
889 io_redirect.Flush();
890 }
891
892 if (success)
893 return true;
894
895 // The one-liner failed. Append the error message.
896 if (result) {
897 result->AppendErrorWithFormat(
898 "python failed attempting to evaluate '%s'\n", command_str.c_str());
899 }
900 return false;
901 }
902
903 if (result)
904 result->AppendError("empty command passed to python\n");
905 return false;
906}
907
908void ScriptInterpreterPythonImpl::ExecuteInterpreterLoop() {
909 LLDB_SCOPED_TIMER()static ::lldb_private::Timer::Category _cat(__PRETTY_FUNCTION__
); ::lldb_private::Timer _scoped_timer(_cat, "%s", __PRETTY_FUNCTION__
)
;
910
911 Debugger &debugger = m_debugger;
912
913 // At the moment, the only time the debugger does not have an input file
914 // handle is when this is called directly from Python, in which case it is
915 // both dangerous and unnecessary (not to mention confusing) to try to embed
916 // a running interpreter loop inside the already running Python interpreter
917 // loop, so we won't do it.
918
919 if (!debugger.GetInputFile().IsValid())
920 return;
921
922 IOHandlerSP io_handler_sp(new IOHandlerPythonInterpreter(debugger, this));
923 if (io_handler_sp) {
924 debugger.RunIOHandlerAsync(io_handler_sp);
925 }
926}
927
928bool ScriptInterpreterPythonImpl::Interrupt() {
929#if LLDB_USE_PYTHON_SET_INTERRUPT(3 == 3 && 9 >= 2) || (3 > 3)
930 // If the interpreter isn't evaluating any Python at the moment then return
931 // false to signal that this function didn't handle the interrupt and the
932 // next component should try handling it.
933 if (!IsExecutingPython())
934 return false;
935
936 // Tell Python that it should pretend to have received a SIGINT.
937 PyErr_SetInterrupt();
938 // PyErr_SetInterrupt has no way to return an error so we can only pretend the
939 // signal got successfully handled and return true.
940 // Python 3.10 introduces PyErr_SetInterruptEx that could return an error, but
941 // the error handling is limited to checking the arguments which would be
942 // just our (hardcoded) input signal code SIGINT, so that's not useful at all.
943 return true;
944#else
945 Log *log = GetLog(LLDBLog::Script);
946
947 if (IsExecutingPython()) {
948 PyThreadState *state = PyThreadState_GET()PyThreadState_Get();
949 if (!state)
950 state = GetThreadState();
951 if (state) {
952 long tid = state->thread_id;
953 PyThreadState_Swap(state);
954 int num_threads = PyThreadState_SetAsyncExc(tid, PyExc_KeyboardInterrupt);
955 LLDB_LOGF(log,do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Printf("ScriptInterpreterPythonImpl::Interrupt() sending "
"PyExc_KeyboardInterrupt (tid = %li, num_threads = %i)...", tid
, num_threads); } while (0)
956 "ScriptInterpreterPythonImpl::Interrupt() sending "do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Printf("ScriptInterpreterPythonImpl::Interrupt() sending "
"PyExc_KeyboardInterrupt (tid = %li, num_threads = %i)...", tid
, num_threads); } while (0)
957 "PyExc_KeyboardInterrupt (tid = %li, num_threads = %i)...",do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Printf("ScriptInterpreterPythonImpl::Interrupt() sending "
"PyExc_KeyboardInterrupt (tid = %li, num_threads = %i)...", tid
, num_threads); } while (0)
958 tid, num_threads)do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Printf("ScriptInterpreterPythonImpl::Interrupt() sending "
"PyExc_KeyboardInterrupt (tid = %li, num_threads = %i)...", tid
, num_threads); } while (0)
;
959 return true;
960 }
961 }
962 LLDB_LOGF(log,do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Printf("ScriptInterpreterPythonImpl::Interrupt() python code not running, "
"can't interrupt"); } while (0)
963 "ScriptInterpreterPythonImpl::Interrupt() python code not running, "do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Printf("ScriptInterpreterPythonImpl::Interrupt() python code not running, "
"can't interrupt"); } while (0)
964 "can't interrupt")do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Printf("ScriptInterpreterPythonImpl::Interrupt() python code not running, "
"can't interrupt"); } while (0)
;
965 return false;
966#endif
967}
968
969bool ScriptInterpreterPythonImpl::ExecuteOneLineWithReturn(
970 llvm::StringRef in_string, ScriptInterpreter::ScriptReturnType return_type,
971 void *ret_value, const ExecuteScriptOptions &options) {
972
973 llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>>
974 io_redirect_or_error = ScriptInterpreterIORedirect::Create(
975 options.GetEnableIO(), m_debugger, /*result=*/nullptr);
976
977 if (!io_redirect_or_error) {
978 llvm::consumeError(io_redirect_or_error.takeError());
979 return false;
980 }
981
982 ScriptInterpreterIORedirect &io_redirect = **io_redirect_or_error;
983
984 Locker locker(this,
985 Locker::AcquireLock | Locker::InitSession |
986 (options.GetSetLLDBGlobals() ? Locker::InitGlobals : 0) |
987 Locker::NoSTDIN,
988 Locker::FreeAcquiredLock | Locker::TearDownSession,
989 io_redirect.GetInputFile(), io_redirect.GetOutputFile(),
990 io_redirect.GetErrorFile());
991
992 PythonModule &main_module = GetMainModule();
993 PythonDictionary globals = main_module.GetDictionary();
994
995 PythonDictionary locals = GetSessionDictionary();
996 if (!locals.IsValid())
997 locals = unwrapIgnoringErrors(
998 As<PythonDictionary>(globals.GetAttribute(m_dictionary_name)));
999 if (!locals.IsValid())
1000 locals = globals;
1001
1002 Expected<PythonObject> maybe_py_return =
1003 runStringOneLine(in_string, globals, locals);
1004
1005 if (!maybe_py_return) {
1006 llvm::handleAllErrors(
1007 maybe_py_return.takeError(),
1008 [&](PythonException &E) {
1009 E.Restore();
1010 if (options.GetMaskoutErrors()) {
1011 if (E.Matches(PyExc_SyntaxError)) {
1012 PyErr_Print();
1013 }
1014 PyErr_Clear();
1015 }
1016 },
1017 [](const llvm::ErrorInfoBase &E) {});
1018 return false;
1019 }
1020
1021 PythonObject py_return = std::move(maybe_py_return.get());
1022 assert(py_return.IsValid())(static_cast <bool> (py_return.IsValid()) ? void (0) : __assert_fail
("py_return.IsValid()", "lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp"
, 1022, __extension__ __PRETTY_FUNCTION__))
;
1023
1024 switch (return_type) {
1025 case eScriptReturnTypeCharPtr: // "char *"
1026 {
1027 const char format[3] = "s#";
1028 return PyArg_Parse(py_return.get(), format, (char **)ret_value);
1029 }
1030 case eScriptReturnTypeCharStrOrNone: // char* or NULL if py_return ==
1031 // Py_None
1032 {
1033 const char format[3] = "z";
1034 return PyArg_Parse(py_return.get(), format, (char **)ret_value);
1035 }
1036 case eScriptReturnTypeBool: {
1037 const char format[2] = "b";
1038 return PyArg_Parse(py_return.get(), format, (bool *)ret_value);
1039 }
1040 case eScriptReturnTypeShortInt: {
1041 const char format[2] = "h";
1042 return PyArg_Parse(py_return.get(), format, (short *)ret_value);
1043 }
1044 case eScriptReturnTypeShortIntUnsigned: {
1045 const char format[2] = "H";
1046 return PyArg_Parse(py_return.get(), format, (unsigned short *)ret_value);
1047 }
1048 case eScriptReturnTypeInt: {
1049 const char format[2] = "i";
1050 return PyArg_Parse(py_return.get(), format, (int *)ret_value);
1051 }
1052 case eScriptReturnTypeIntUnsigned: {
1053 const char format[2] = "I";
1054 return PyArg_Parse(py_return.get(), format, (unsigned int *)ret_value);
1055 }
1056 case eScriptReturnTypeLongInt: {
1057 const char format[2] = "l";
1058 return PyArg_Parse(py_return.get(), format, (long *)ret_value);
1059 }
1060 case eScriptReturnTypeLongIntUnsigned: {
1061 const char format[2] = "k";
1062 return PyArg_Parse(py_return.get(), format, (unsigned long *)ret_value);
1063 }
1064 case eScriptReturnTypeLongLong: {
1065 const char format[2] = "L";
1066 return PyArg_Parse(py_return.get(), format, (long long *)ret_value);
1067 }
1068 case eScriptReturnTypeLongLongUnsigned: {
1069 const char format[2] = "K";
1070 return PyArg_Parse(py_return.get(), format,
1071 (unsigned long long *)ret_value);
1072 }
1073 case eScriptReturnTypeFloat: {
1074 const char format[2] = "f";
1075 return PyArg_Parse(py_return.get(), format, (float *)ret_value);
1076 }
1077 case eScriptReturnTypeDouble: {
1078 const char format[2] = "d";
1079 return PyArg_Parse(py_return.get(), format, (double *)ret_value);
1080 }
1081 case eScriptReturnTypeChar: {
1082 const char format[2] = "c";
1083 return PyArg_Parse(py_return.get(), format, (char *)ret_value);
1084 }
1085 case eScriptReturnTypeOpaqueObject: {
1086 *((PyObject **)ret_value) = py_return.release();
1087 return true;
1088 }
1089 }
1090 llvm_unreachable("Fully covered switch!")::llvm::llvm_unreachable_internal("Fully covered switch!", "lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp"
, 1090)
;
1091}
1092
1093Status ScriptInterpreterPythonImpl::ExecuteMultipleLines(
1094 const char *in_string, const ExecuteScriptOptions &options) {
1095
1096 if (in_string == nullptr)
1097 return Status();
1098
1099 llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>>
1100 io_redirect_or_error = ScriptInterpreterIORedirect::Create(
1101 options.GetEnableIO(), m_debugger, /*result=*/nullptr);
1102
1103 if (!io_redirect_or_error)
1104 return Status(io_redirect_or_error.takeError());
1105
1106 ScriptInterpreterIORedirect &io_redirect = **io_redirect_or_error;
1107
1108 Locker locker(this,
1109 Locker::AcquireLock | Locker::InitSession |
1110 (options.GetSetLLDBGlobals() ? Locker::InitGlobals : 0) |
1111 Locker::NoSTDIN,
1112 Locker::FreeAcquiredLock | Locker::TearDownSession,
1113 io_redirect.GetInputFile(), io_redirect.GetOutputFile(),
1114 io_redirect.GetErrorFile());
1115
1116 PythonModule &main_module = GetMainModule();
1117 PythonDictionary globals = main_module.GetDictionary();
1118
1119 PythonDictionary locals = GetSessionDictionary();
1120 if (!locals.IsValid())
1121 locals = unwrapIgnoringErrors(
1122 As<PythonDictionary>(globals.GetAttribute(m_dictionary_name)));
1123 if (!locals.IsValid())
1124 locals = globals;
1125
1126 Expected<PythonObject> return_value =
1127 runStringMultiLine(in_string, globals, locals);
1128
1129 if (!return_value) {
1130 llvm::Error error =
1131 llvm::handleErrors(return_value.takeError(), [&](PythonException &E) {
1132 llvm::Error error = llvm::createStringError(
1133 llvm::inconvertibleErrorCode(), E.ReadBacktrace());
1134 if (!options.GetMaskoutErrors())
1135 E.Restore();
1136 return error;
1137 });
1138 return Status(std::move(error));
1139 }
1140
1141 return Status();
1142}
1143
1144void ScriptInterpreterPythonImpl::CollectDataForBreakpointCommandCallback(
1145 std::vector<std::reference_wrapper<BreakpointOptions>> &bp_options_vec,
1146 CommandReturnObject &result) {
1147 m_active_io_handler = eIOHandlerBreakpoint;
1148 m_debugger.GetCommandInterpreter().GetPythonCommandsFromIOHandler(
1149 " ", *this, &bp_options_vec);
1150}
1151
1152void ScriptInterpreterPythonImpl::CollectDataForWatchpointCommandCallback(
1153 WatchpointOptions *wp_options, CommandReturnObject &result) {
1154 m_active_io_handler = eIOHandlerWatchpoint;
1155 m_debugger.GetCommandInterpreter().GetPythonCommandsFromIOHandler(
1156 " ", *this, wp_options);
1157}
1158
1159Status ScriptInterpreterPythonImpl::SetBreakpointCommandCallbackFunction(
1160 BreakpointOptions &bp_options, const char *function_name,
1161 StructuredData::ObjectSP extra_args_sp) {
1162 Status error;
1163 // For now just cons up a oneliner that calls the provided function.
1164 std::string function_signature = function_name;
1165
1166 llvm::Expected<unsigned> maybe_args =
1167 GetMaxPositionalArgumentsForCallable(function_name);
1168 if (!maybe_args) {
1169 error.SetErrorStringWithFormat(
1170 "could not get num args: %s",
1171 llvm::toString(maybe_args.takeError()).c_str());
1172 return error;
1173 }
1174 size_t max_args = *maybe_args;
1175
1176 bool uses_extra_args = false;
1177 if (max_args >= 4) {
1178 uses_extra_args = true;
1179 function_signature += "(frame, bp_loc, extra_args, internal_dict)";
1180 } else if (max_args >= 3) {
1181 if (extra_args_sp) {
1182 error.SetErrorString("cannot pass extra_args to a three argument callback"
1183 );
1184 return error;
1185 }
1186 uses_extra_args = false;
1187 function_signature += "(frame, bp_loc, internal_dict)";
1188 } else {
1189 error.SetErrorStringWithFormat("expected 3 or 4 argument "
1190 "function, %s can only take %zu",
1191 function_name, max_args);
1192 return error;
1193 }
1194
1195 SetBreakpointCommandCallback(bp_options, function_signature.c_str(),
1196 extra_args_sp, uses_extra_args,
1197 /*is_callback=*/true);
1198 return error;
1199}
1200
1201Status ScriptInterpreterPythonImpl::SetBreakpointCommandCallback(
1202 BreakpointOptions &bp_options,
1203 std::unique_ptr<BreakpointOptions::CommandData> &cmd_data_up) {
1204 Status error;
1205 error = GenerateBreakpointCommandCallbackData(cmd_data_up->user_source,
1206 cmd_data_up->script_source,
1207 /*has_extra_args=*/false,
1208 /*is_callback=*/false);
1209 if (error.Fail()) {
1210 return error;
1211 }
1212 auto baton_sp =
1213 std::make_shared<BreakpointOptions::CommandBaton>(std::move(cmd_data_up));
1214 bp_options.SetCallback(
1215 ScriptInterpreterPythonImpl::BreakpointCallbackFunction, baton_sp);
1216 return error;
1217}
1218
1219Status ScriptInterpreterPythonImpl::SetBreakpointCommandCallback(
1220 BreakpointOptions &bp_options, const char *command_body_text,
1221 bool is_callback) {
1222 return SetBreakpointCommandCallback(bp_options, command_body_text, {},
1223 /*uses_extra_args=*/false, is_callback);
1224}
1225
1226// Set a Python one-liner as the callback for the breakpoint.
1227Status ScriptInterpreterPythonImpl::SetBreakpointCommandCallback(
1228 BreakpointOptions &bp_options, const char *command_body_text,
1229 StructuredData::ObjectSP extra_args_sp, bool uses_extra_args,
1230 bool is_callback) {
1231 auto data_up = std::make_unique<CommandDataPython>(extra_args_sp);
1232 // Split the command_body_text into lines, and pass that to
1233 // GenerateBreakpointCommandCallbackData. That will wrap the body in an
1234 // auto-generated function, and return the function name in script_source.
1235 // That is what the callback will actually invoke.
1236
1237 data_up->user_source.SplitIntoLines(command_body_text);
1238 Status error = GenerateBreakpointCommandCallbackData(
1239 data_up->user_source, data_up->script_source, uses_extra_args,
1240 is_callback);
1241 if (error.Success()) {
1242 auto baton_sp =
1243 std::make_shared<BreakpointOptions::CommandBaton>(std::move(data_up));
1244 bp_options.SetCallback(
1245 ScriptInterpreterPythonImpl::BreakpointCallbackFunction, baton_sp);
1246 return error;
1247 }
1248 return error;
1249}
1250
1251// Set a Python one-liner as the callback for the watchpoint.
1252void ScriptInterpreterPythonImpl::SetWatchpointCommandCallback(
1253 WatchpointOptions *wp_options, const char *user_input,
1254 bool is_callback) {
1255 auto data_up = std::make_unique<WatchpointOptions::CommandData>();
1256
1257 // It's necessary to set both user_source and script_source to the oneliner.
1258 // The former is used to generate callback description (as in watchpoint
1259 // command list) while the latter is used for Python to interpret during the
1260 // actual callback.
1261
1262 data_up->user_source.AppendString(user_input);
1263 data_up->script_source.assign(user_input);
1264
1265 if (GenerateWatchpointCommandCallbackData(
1266 data_up->user_source, data_up->script_source, is_callback)) {
1267 auto baton_sp =
1268 std::make_shared<WatchpointOptions::CommandBaton>(std::move(data_up));
1269 wp_options->SetCallback(
1270 ScriptInterpreterPythonImpl::WatchpointCallbackFunction, baton_sp);
1271 }
1272}
1273
1274Status ScriptInterpreterPythonImpl::ExportFunctionDefinitionToInterpreter(
1275 StringList &function_def) {
1276 // Convert StringList to one long, newline delimited, const char *.
1277 std::string function_def_string(function_def.CopyList());
1278
1279 Status error = ExecuteMultipleLines(
1280 function_def_string.c_str(),
1281 ExecuteScriptOptions().SetEnableIO(false));
1282 return error;
1283}
1284
1285Status ScriptInterpreterPythonImpl::GenerateFunction(const char *signature,
1286 const StringList &input,
1287 bool is_callback) {
1288 Status error;
1289 int num_lines = input.GetSize();
1290 if (num_lines == 0) {
1291 error.SetErrorString("No input data.");
1292 return error;
1293 }
1294
1295 if (!signature || *signature == 0) {
1296 error.SetErrorString("No output function name.");
1297 return error;
1298 }
1299
1300 StreamString sstr;
1301 StringList auto_generated_function;
1302 auto_generated_function.AppendString(signature);
1303 auto_generated_function.AppendString(
1304 " global_dict = globals()"); // Grab the global dictionary
1305 auto_generated_function.AppendString(
1306 " new_keys = internal_dict.keys()"); // Make a list of keys in the
1307 // session dict
1308 auto_generated_function.AppendString(
1309 " old_keys = global_dict.keys()"); // Save list of keys in global dict
1310 auto_generated_function.AppendString(
1311 " global_dict.update(internal_dict)"); // Add the session dictionary
1312 // to the global dictionary.
1313
1314 if (is_callback) {
1315 // If the user input is a callback to a python function, make sure the input
1316 // is only 1 line, otherwise appending the user input would break the
1317 // generated wrapped function
1318 if (num_lines == 1) {
1319 sstr.Clear();
1320 sstr.Printf(" __return_val = %s", input.GetStringAtIndex(0));
1321 auto_generated_function.AppendString(sstr.GetData());
1322 } else {
1323 return Status("ScriptInterpreterPythonImpl::GenerateFunction(is_callback="
1324 "true) = ERROR: python function is multiline.");
1325 }
1326 } else {
1327 auto_generated_function.AppendString(
1328 " __return_val = None"); // Initialize user callback return value.
1329 auto_generated_function.AppendString(
1330 " def __user_code():"); // Create a nested function that will wrap
1331 // the user input. This is necessary to
1332 // capture the return value of the user input
1333 // and prevent early returns.
1334 for (int i = 0; i < num_lines; ++i) {
1335 sstr.Clear();
1336 sstr.Printf(" %s", input.GetStringAtIndex(i));
1337 auto_generated_function.AppendString(sstr.GetData());
1338 }
1339 auto_generated_function.AppendString(
1340 " __return_val = __user_code()"); // Call user code and capture
1341 // return value
1342 }
1343 auto_generated_function.AppendString(
1344 " for key in new_keys:"); // Iterate over all the keys from session
1345 // dict
1346 auto_generated_function.AppendString(
1347 " internal_dict[key] = global_dict[key]"); // Update session dict
1348 // values
1349 auto_generated_function.AppendString(
1350 " if key not in old_keys:"); // If key was not originally in
1351 // global dict
1352 auto_generated_function.AppendString(
1353 " del global_dict[key]"); // ...then remove key/value from
1354 // global dict
1355 auto_generated_function.AppendString(
1356 " return __return_val"); // Return the user callback return value.
1357
1358 // Verify that the results are valid Python.
1359 error = ExportFunctionDefinitionToInterpreter(auto_generated_function);
1360
1361 return error;
1362}
1363
1364bool ScriptInterpreterPythonImpl::GenerateTypeScriptFunction(
1365 StringList &user_input, std::string &output, const void *name_token) {
1366 static uint32_t num_created_functions = 0;
1367 user_input.RemoveBlankLines();
1368 StreamString sstr;
1369
1370 // Check to see if we have any data; if not, just return.
1371 if (user_input.GetSize() == 0)
1372 return false;
1373
1374 // Take what the user wrote, wrap it all up inside one big auto-generated
1375 // Python function, passing in the ValueObject as parameter to the function.
1376
1377 std::string auto_generated_function_name(
1378 GenerateUniqueName("lldb_autogen_python_type_print_func",
1379 num_created_functions, name_token));
1380 sstr.Printf("def %s (valobj, internal_dict):",
1381 auto_generated_function_name.c_str());
1382
1383 if (!GenerateFunction(sstr.GetData(), user_input, /*is_callback=*/false)
1384 .Success())
1385 return false;
1386
1387 // Store the name of the auto-generated function to be called.
1388 output.assign(auto_generated_function_name);
1389 return true;
1390}
1391
1392bool ScriptInterpreterPythonImpl::GenerateScriptAliasFunction(
1393 StringList &user_input, std::string &output) {
1394 static uint32_t num_created_functions = 0;
1395 user_input.RemoveBlankLines();
1396 StreamString sstr;
1397
1398 // Check to see if we have any data; if not, just return.
1399 if (user_input.GetSize() == 0)
1400 return false;
1401
1402 std::string auto_generated_function_name(GenerateUniqueName(
1403 "lldb_autogen_python_cmd_alias_func", num_created_functions));
1404
1405 sstr.Printf("def %s (debugger, args, exe_ctx, result, internal_dict):",
1406 auto_generated_function_name.c_str());
1407
1408 if (!GenerateFunction(sstr.GetData(), user_input, /*is_callback=*/true)
1409 .Success())
1410 return false;
1411
1412 // Store the name of the auto-generated function to be called.
1413 output.assign(auto_generated_function_name);
1414 return true;
1415}
1416
1417bool ScriptInterpreterPythonImpl::GenerateTypeSynthClass(
1418 StringList &user_input, std::string &output, const void *name_token) {
1419 static uint32_t num_created_classes = 0;
1420 user_input.RemoveBlankLines();
1421 int num_lines = user_input.GetSize();
1422 StreamString sstr;
1423
1424 // Check to see if we have any data; if not, just return.
1425 if (user_input.GetSize() == 0)
1426 return false;
1427
1428 // Wrap all user input into a Python class
1429
1430 std::string auto_generated_class_name(GenerateUniqueName(
1431 "lldb_autogen_python_type_synth_class", num_created_classes, name_token));
1432
1433 StringList auto_generated_class;
1434
1435 // Create the function name & definition string.
1436
1437 sstr.Printf("class %s:", auto_generated_class_name.c_str());
1438 auto_generated_class.AppendString(sstr.GetString());
1439
1440 // Wrap everything up inside the class, increasing the indentation. we don't
1441 // need to play any fancy indentation tricks here because there is no
1442 // surrounding code whose indentation we need to honor
1443 for (int i = 0; i < num_lines; ++i) {
1444 sstr.Clear();
1445 sstr.Printf(" %s", user_input.GetStringAtIndex(i));
1446 auto_generated_class.AppendString(sstr.GetString());
1447 }
1448
1449 // Verify that the results are valid Python. (even though the method is
1450 // ExportFunctionDefinitionToInterpreter, a class will actually be exported)
1451 // (TODO: rename that method to ExportDefinitionToInterpreter)
1452 if (!ExportFunctionDefinitionToInterpreter(auto_generated_class).Success())
1453 return false;
1454
1455 // Store the name of the auto-generated class
1456
1457 output.assign(auto_generated_class_name);
1458 return true;
1459}
1460
1461StructuredData::GenericSP
1462ScriptInterpreterPythonImpl::CreateFrameRecognizer(const char *class_name) {
1463 if (class_name == nullptr || class_name[0] == '\0')
1464 return StructuredData::GenericSP();
1465
1466 Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
1467 PythonObject ret_val = LLDBSWIGPython_CreateFrameRecognizer(
1468 class_name, m_dictionary_name.c_str());
1469
1470 return StructuredData::GenericSP(
1471 new StructuredPythonObject(std::move(ret_val)));
1472}
1473
1474lldb::ValueObjectListSP ScriptInterpreterPythonImpl::GetRecognizedArguments(
1475 const StructuredData::ObjectSP &os_plugin_object_sp,
1476 lldb::StackFrameSP frame_sp) {
1477 Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
1478
1479 if (!os_plugin_object_sp)
1480 return ValueObjectListSP();
1481
1482 StructuredData::Generic *generic = os_plugin_object_sp->GetAsGeneric();
1483 if (!generic)
1484 return nullptr;
1485
1486 PythonObject implementor(PyRefType::Borrowed,
1487 (PyObject *)generic->GetValue());
1488
1489 if (!implementor.IsAllocated())
1490 return ValueObjectListSP();
1491
1492 PythonObject py_return(
1493 PyRefType::Owned,
1494 LLDBSwigPython_GetRecognizedArguments(implementor.get(), frame_sp));
1495
1496 // if it fails, print the error but otherwise go on
1497 if (PyErr_Occurred()) {
1498 PyErr_Print();
1499 PyErr_Clear();
1500 }
1501 if (py_return.get()) {
1502 PythonList result_list(PyRefType::Borrowed, py_return.get());
1503 ValueObjectListSP result = ValueObjectListSP(new ValueObjectList());
1504 for (size_t i = 0; i < result_list.GetSize(); i++) {
1505 PyObject *item = result_list.GetItemAtIndex(i).get();
1506 lldb::SBValue *sb_value_ptr =
1507 (lldb::SBValue *)LLDBSWIGPython_CastPyObjectToSBValue(item);
1508 auto valobj_sp = LLDBSWIGPython_GetValueObjectSPFromSBValue(sb_value_ptr);
1509 if (valobj_sp)
1510 result->Append(valobj_sp);
1511 }
1512 return result;
1513 }
1514 return ValueObjectListSP();
1515}
1516
1517ScriptedProcessInterfaceUP
1518ScriptInterpreterPythonImpl::CreateScriptedProcessInterface() {
1519 return std::make_unique<ScriptedProcessPythonInterface>(*this);
1520}
1521
1522StructuredData::GenericSP
1523ScriptInterpreterPythonImpl::OSPlugin_CreatePluginObject(
1524 const char *class_name, lldb::ProcessSP process_sp) {
1525 if (class_name == nullptr || class_name[0] == '\0')
1526 return StructuredData::GenericSP();
1527
1528 if (!process_sp)
1529 return StructuredData::GenericSP();
1530
1531 Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
1532 PythonObject ret_val = LLDBSWIGPythonCreateOSPlugin(
1533 class_name, m_dictionary_name.c_str(), process_sp);
1534
1535 return StructuredData::GenericSP(
1536 new StructuredPythonObject(std::move(ret_val)));
1537}
1538
1539StructuredData::DictionarySP ScriptInterpreterPythonImpl::OSPlugin_RegisterInfo(
1540 StructuredData::ObjectSP os_plugin_object_sp) {
1541 Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
1542
1543 if (!os_plugin_object_sp)
1544 return {};
1545
1546 StructuredData::Generic *generic = os_plugin_object_sp->GetAsGeneric();
1547 if (!generic)
1548 return {};
1549
1550 PythonObject implementor(PyRefType::Borrowed,
1551 (PyObject *)generic->GetValue());
1552
1553 if (!implementor.IsAllocated())
1554 return {};
1555
1556 llvm::Expected<PythonObject> expected_py_return =
1557 implementor.CallMethod("get_register_info");
1558
1559 if (!expected_py_return) {
1560 llvm::consumeError(expected_py_return.takeError());
1561 return {};
1562 }
1563
1564 PythonObject py_return = std::move(expected_py_return.get());
1565
1566 if (py_return.get()) {
1567 PythonDictionary result_dict(PyRefType::Borrowed, py_return.get());
1568 return result_dict.CreateStructuredDictionary();
1569 }
1570 return StructuredData::DictionarySP();
1571}
1572
1573StructuredData::ArraySP ScriptInterpreterPythonImpl::OSPlugin_ThreadsInfo(
1574 StructuredData::ObjectSP os_plugin_object_sp) {
1575 Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
1576 if (!os_plugin_object_sp)
1577 return {};
1578
1579 StructuredData::Generic *generic = os_plugin_object_sp->GetAsGeneric();
1580 if (!generic)
1581 return {};
1582
1583 PythonObject implementor(PyRefType::Borrowed,
1584 (PyObject *)generic->GetValue());
1585
1586 if (!implementor.IsAllocated())
1587 return {};
1588
1589 llvm::Expected<PythonObject> expected_py_return =
1590 implementor.CallMethod("get_thread_info");
1591
1592 if (!expected_py_return) {
1593 llvm::consumeError(expected_py_return.takeError());
1594 return {};
1595 }
1596
1597 PythonObject py_return = std::move(expected_py_return.get());
1598
1599 if (py_return.get()) {
1600 PythonList result_list(PyRefType::Borrowed, py_return.get());
1601 return result_list.CreateStructuredArray();
1602 }
1603 return StructuredData::ArraySP();
1604}
1605
1606StructuredData::StringSP
1607ScriptInterpreterPythonImpl::OSPlugin_RegisterContextData(
1608 StructuredData::ObjectSP os_plugin_object_sp, lldb::tid_t tid) {
1609 Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
1610
1611 if (!os_plugin_object_sp)
1612 return {};
1613
1614 StructuredData::Generic *generic = os_plugin_object_sp->GetAsGeneric();
1615 if (!generic)
1616 return {};
1617 PythonObject implementor(PyRefType::Borrowed,
1618 (PyObject *)generic->GetValue());
1619
1620 if (!implementor.IsAllocated())
1621 return {};
1622
1623 llvm::Expected<PythonObject> expected_py_return =
1624 implementor.CallMethod("get_register_data", tid);
1625
1626 if (!expected_py_return) {
1627 llvm::consumeError(expected_py_return.takeError());
1628 return {};
1629 }
1630
1631 PythonObject py_return = std::move(expected_py_return.get());
1632
1633 if (py_return.get()) {
1634 PythonBytes result(PyRefType::Borrowed, py_return.get());
1635 return result.CreateStructuredString();
1636 }
1637 return {};
1638}
1639
1640StructuredData::DictionarySP ScriptInterpreterPythonImpl::OSPlugin_CreateThread(
1641 StructuredData::ObjectSP os_plugin_object_sp, lldb::tid_t tid,
1642 lldb::addr_t context) {
1643 Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
1644
1645 if (!os_plugin_object_sp)
1646 return {};
1647
1648 StructuredData::Generic *generic = os_plugin_object_sp->GetAsGeneric();
1649 if (!generic)
1650 return {};
1651
1652 PythonObject implementor(PyRefType::Borrowed,
1653 (PyObject *)generic->GetValue());
1654
1655 if (!implementor.IsAllocated())
1656 return {};
1657
1658 llvm::Expected<PythonObject> expected_py_return =
1659 implementor.CallMethod("create_thread", tid, context);
1660
1661 if (!expected_py_return) {
1662 llvm::consumeError(expected_py_return.takeError());
1663 return {};
1664 }
1665
1666 PythonObject py_return = std::move(expected_py_return.get());
1667
1668 if (py_return.get()) {
1669 PythonDictionary result_dict(PyRefType::Borrowed, py_return.get());
1670 return result_dict.CreateStructuredDictionary();
1671 }
1672 return StructuredData::DictionarySP();
1673}
1674
1675StructuredData::ObjectSP ScriptInterpreterPythonImpl::CreateScriptedThreadPlan(
1676 const char *class_name, const StructuredDataImpl &args_data,
1677 std::string &error_str, lldb::ThreadPlanSP thread_plan_sp) {
1678 if (class_name == nullptr || class_name[0] == '\0')
1679 return StructuredData::ObjectSP();
1680
1681 if (!thread_plan_sp.get())
1682 return {};
1683
1684 Debugger &debugger = thread_plan_sp->GetTarget().GetDebugger();
1685 ScriptInterpreterPythonImpl *python_interpreter =
1686 GetPythonInterpreter(debugger);
1687
1688 if (!python_interpreter)
1689 return {};
1690
1691 Locker py_lock(this,
1692 Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
1693 PythonObject ret_val = LLDBSwigPythonCreateScriptedThreadPlan(
1694 class_name, python_interpreter->m_dictionary_name.c_str(), args_data,
1695 error_str, thread_plan_sp);
1696 if (!ret_val)
1697 return {};
1698
1699 return StructuredData::ObjectSP(
1700 new StructuredPythonObject(std::move(ret_val)));
1701}
1702
1703bool ScriptInterpreterPythonImpl::ScriptedThreadPlanExplainsStop(
1704 StructuredData::ObjectSP implementor_sp, Event *event, bool &script_error) {
1705 bool explains_stop = true;
1706 StructuredData::Generic *generic = nullptr;
1707 if (implementor_sp)
1708 generic = implementor_sp->GetAsGeneric();
1709 if (generic) {
1710 Locker py_lock(this,
1711 Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
1712 explains_stop = LLDBSWIGPythonCallThreadPlan(
1713 generic->GetValue(), "explains_stop", event, script_error);
1714 if (script_error)
1715 return true;
1716 }
1717 return explains_stop;
1718}
1719
1720bool ScriptInterpreterPythonImpl::ScriptedThreadPlanShouldStop(
1721 StructuredData::ObjectSP implementor_sp, Event *event, bool &script_error) {
1722 bool should_stop = true;
1723 StructuredData::Generic *generic = nullptr;
1724 if (implementor_sp)
1725 generic = implementor_sp->GetAsGeneric();
1726 if (generic) {
1727 Locker py_lock(this,
1728 Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
1729 should_stop = LLDBSWIGPythonCallThreadPlan(
1730 generic->GetValue(), "should_stop", event, script_error);
1731 if (script_error)
1732 return true;
1733 }
1734 return should_stop;
1735}
1736
1737bool ScriptInterpreterPythonImpl::ScriptedThreadPlanIsStale(
1738 StructuredData::ObjectSP implementor_sp, bool &script_error) {
1739 bool is_stale = true;
1740 StructuredData::Generic *generic = nullptr;
1741 if (implementor_sp)
1742 generic = implementor_sp->GetAsGeneric();
1743 if (generic) {
1744 Locker py_lock(this,
1745 Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
1746 is_stale = LLDBSWIGPythonCallThreadPlan(generic->GetValue(), "is_stale",
1747 (Event *) nullptr, script_error);
1748 if (script_error)
1749 return true;
1750 }
1751 return is_stale;
1752}
1753
1754lldb::StateType ScriptInterpreterPythonImpl::ScriptedThreadPlanGetRunState(
1755 StructuredData::ObjectSP implementor_sp, bool &script_error) {
1756 bool should_step = false;
1757 StructuredData::Generic *generic = nullptr;
1758 if (implementor_sp)
1759 generic = implementor_sp->GetAsGeneric();
1760 if (generic) {
1761 Locker py_lock(this,
1762 Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
1763 should_step = LLDBSWIGPythonCallThreadPlan(
1764 generic->GetValue(), "should_step", (Event *) nullptr, script_error);
1765 if (script_error)
1766 should_step = true;
1767 }
1768 if (should_step)
1769 return lldb::eStateStepping;
1770 return lldb::eStateRunning;
1771}
1772
1773bool
1774ScriptInterpreterPythonImpl::ScriptedThreadPlanGetStopDescription(
1775 StructuredData::ObjectSP implementor_sp, lldb_private::Stream *stream,
1776 bool &script_error) {
1777 StructuredData::Generic *generic = nullptr;
1778 if (implementor_sp)
1779 generic = implementor_sp->GetAsGeneric();
1780 if (!generic) {
1781 script_error = true;
1782 return false;
1783 }
1784 Locker py_lock(this,
1785 Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
1786 return LLDBSWIGPythonCallThreadPlan(generic->GetValue(), "stop_description",
1787 stream, script_error);
1788}
1789
1790
1791StructuredData::GenericSP
1792ScriptInterpreterPythonImpl::CreateScriptedBreakpointResolver(
1793 const char *class_name, const StructuredDataImpl &args_data,
1794 lldb::BreakpointSP &bkpt_sp) {
1795
1796 if (class_name == nullptr || class_name[0] == '\0')
1797 return StructuredData::GenericSP();
1798
1799 if (!bkpt_sp.get())
1800 return StructuredData::GenericSP();
1801
1802 Debugger &debugger = bkpt_sp->GetTarget().GetDebugger();
1803 ScriptInterpreterPythonImpl *python_interpreter =
1804 GetPythonInterpreter(debugger);
1805
1806 if (!python_interpreter)
1807 return StructuredData::GenericSP();
1808
1809 Locker py_lock(this,
1810 Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
1811
1812 PythonObject ret_val = LLDBSwigPythonCreateScriptedBreakpointResolver(
1813 class_name, python_interpreter->m_dictionary_name.c_str(), args_data,
1814 bkpt_sp);
1815
1816 return StructuredData::GenericSP(
1817 new StructuredPythonObject(std::move(ret_val)));
1818}
1819
1820bool ScriptInterpreterPythonImpl::ScriptedBreakpointResolverSearchCallback(
1821 StructuredData::GenericSP implementor_sp, SymbolContext *sym_ctx) {
1822 bool should_continue = false;
1823
1824 if (implementor_sp) {
1825 Locker py_lock(this,
1826 Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
1827 should_continue = LLDBSwigPythonCallBreakpointResolver(
1828 implementor_sp->GetValue(), "__callback__", sym_ctx);
1829 if (PyErr_Occurred()) {
1830 PyErr_Print();
1831 PyErr_Clear();
1832 }
1833 }
1834 return should_continue;
1835}
1836
1837lldb::SearchDepth
1838ScriptInterpreterPythonImpl::ScriptedBreakpointResolverSearchDepth(
1839 StructuredData::GenericSP implementor_sp) {
1840 int depth_as_int = lldb::eSearchDepthModule;
1841 if (implementor_sp) {
1842 Locker py_lock(this,
1843 Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
1844 depth_as_int = LLDBSwigPythonCallBreakpointResolver(
1845 implementor_sp->GetValue(), "__get_depth__", nullptr);
1846 if (PyErr_Occurred()) {
1847 PyErr_Print();
1848 PyErr_Clear();
1849 }
1850 }
1851 if (depth_as_int == lldb::eSearchDepthInvalid)
1852 return lldb::eSearchDepthModule;
1853
1854 if (depth_as_int <= lldb::kLastSearchDepthKind)
1855 return (lldb::SearchDepth)depth_as_int;
1856 return lldb::eSearchDepthModule;
1857}
1858
1859StructuredData::GenericSP ScriptInterpreterPythonImpl::CreateScriptedStopHook(
1860 TargetSP target_sp, const char *class_name,
1861 const StructuredDataImpl &args_data, Status &error) {
1862
1863 if (!target_sp) {
1864 error.SetErrorString("No target for scripted stop-hook.");
1865 return StructuredData::GenericSP();
1866 }
1867
1868 if (class_name == nullptr || class_name[0] == '\0') {
1869 error.SetErrorString("No class name for scripted stop-hook.");
1870 return StructuredData::GenericSP();
1871 }
1872
1873 ScriptInterpreterPythonImpl *python_interpreter =
1874 GetPythonInterpreter(m_debugger);
1875
1876 if (!python_interpreter) {
1877 error.SetErrorString("No script interpreter for scripted stop-hook.");
1878 return StructuredData::GenericSP();
1879 }
1880
1881 Locker py_lock(this,
1882 Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
1883
1884 PythonObject ret_val = LLDBSwigPythonCreateScriptedStopHook(
1885 target_sp, class_name, python_interpreter->m_dictionary_name.c_str(),
1886 args_data, error);
1887
1888 return StructuredData::GenericSP(
1889 new StructuredPythonObject(std::move(ret_val)));
1890}
1891
1892bool ScriptInterpreterPythonImpl::ScriptedStopHookHandleStop(
1893 StructuredData::GenericSP implementor_sp, ExecutionContext &exc_ctx,
1894 lldb::StreamSP stream_sp) {
1895 assert(implementor_sp &&(static_cast <bool> (implementor_sp && "can't call a stop hook with an invalid implementor"
) ? void (0) : __assert_fail ("implementor_sp && \"can't call a stop hook with an invalid implementor\""
, "lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp"
, 1896, __extension__ __PRETTY_FUNCTION__))
1896 "can't call a stop hook with an invalid implementor")(static_cast <bool> (implementor_sp && "can't call a stop hook with an invalid implementor"
) ? void (0) : __assert_fail ("implementor_sp && \"can't call a stop hook with an invalid implementor\""
, "lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp"
, 1896, __extension__ __PRETTY_FUNCTION__))
;
1897 assert(stream_sp && "can't call a stop hook with an invalid stream")(static_cast <bool> (stream_sp && "can't call a stop hook with an invalid stream"
) ? void (0) : __assert_fail ("stream_sp && \"can't call a stop hook with an invalid stream\""
, "lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp"
, 1897, __extension__ __PRETTY_FUNCTION__))
;
1898
1899 Locker py_lock(this,
1900 Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
1901
1902 lldb::ExecutionContextRefSP exc_ctx_ref_sp(new ExecutionContextRef(exc_ctx));
1903
1904 bool ret_val = LLDBSwigPythonStopHookCallHandleStop(
1905 implementor_sp->GetValue(), exc_ctx_ref_sp, stream_sp);
1906 return ret_val;
1907}
1908
1909StructuredData::ObjectSP
1910ScriptInterpreterPythonImpl::LoadPluginModule(const FileSpec &file_spec,
1911 lldb_private::Status &error) {
1912 if (!FileSystem::Instance().Exists(file_spec)) {
1913 error.SetErrorString("no such file");
1914 return StructuredData::ObjectSP();
1915 }
1916
1917 StructuredData::ObjectSP module_sp;
1918
1919 LoadScriptOptions load_script_options =
1920 LoadScriptOptions().SetInitSession(true).SetSilent(false);
1921 if (LoadScriptingModule(file_spec.GetPath().c_str(), load_script_options,
1922 error, &module_sp))
1923 return module_sp;
1924
1925 return StructuredData::ObjectSP();
1926}
1927
1928StructuredData::DictionarySP ScriptInterpreterPythonImpl::GetDynamicSettings(
1929 StructuredData::ObjectSP plugin_module_sp, Target *target,
1930 const char *setting_name, lldb_private::Status &error) {
1931 if (!plugin_module_sp || !target || !setting_name || !setting_name[0])
1932 return StructuredData::DictionarySP();
1933 StructuredData::Generic *generic = plugin_module_sp->GetAsGeneric();
1934 if (!generic)
1935 return StructuredData::DictionarySP();
1936
1937 Locker py_lock(this,
1938 Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
1939 TargetSP target_sp(target->shared_from_this());
1940
1941 auto setting = (PyObject *)LLDBSWIGPython_GetDynamicSetting(
1942 generic->GetValue(), setting_name, target_sp);
1943
1944 if (!setting)
1945 return StructuredData::DictionarySP();
1946
1947 PythonDictionary py_dict =
1948 unwrapIgnoringErrors(As<PythonDictionary>(Take<PythonObject>(setting)));
1949
1950 if (!py_dict)
1951 return StructuredData::DictionarySP();
1952
1953 return py_dict.CreateStructuredDictionary();
1954}
1955
1956StructuredData::ObjectSP
1957ScriptInterpreterPythonImpl::CreateSyntheticScriptedProvider(
1958 const char *class_name, lldb::ValueObjectSP valobj) {
1959 if (class_name == nullptr || class_name[0] == '\0')
1960 return StructuredData::ObjectSP();
1961
1962 if (!valobj.get())
1963 return StructuredData::ObjectSP();
1964
1965 ExecutionContext exe_ctx(valobj->GetExecutionContextRef());
1966 Target *target = exe_ctx.GetTargetPtr();
1967
1968 if (!target)
1969 return StructuredData::ObjectSP();
1970
1971 Debugger &debugger = target->GetDebugger();
1972 ScriptInterpreterPythonImpl *python_interpreter =
1973 GetPythonInterpreter(debugger);
1974
1975 if (!python_interpreter)
1976 return StructuredData::ObjectSP();
1977
1978 Locker py_lock(this,
1979 Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
1980 PythonObject ret_val = LLDBSwigPythonCreateSyntheticProvider(
1981 class_name, python_interpreter->m_dictionary_name.c_str(), valobj);
1982
1983 return StructuredData::ObjectSP(
1984 new StructuredPythonObject(std::move(ret_val)));
1985}
1986
1987StructuredData::GenericSP
1988ScriptInterpreterPythonImpl::CreateScriptCommandObject(const char *class_name) {
1989 DebuggerSP debugger_sp(m_debugger.shared_from_this());
1990
1991 if (class_name == nullptr || class_name[0] == '\0')
1992 return StructuredData::GenericSP();
1993
1994 if (!debugger_sp.get())
1995 return StructuredData::GenericSP();
1996
1997 Locker py_lock(this,
1998 Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
1999 PythonObject ret_val = LLDBSwigPythonCreateCommandObject(
2000 class_name, m_dictionary_name.c_str(), debugger_sp);
2001
2002 if (ret_val.IsValid())
2003 return StructuredData::GenericSP(
2004 new StructuredPythonObject(std::move(ret_val)));
2005 else
2006 return {};
2007}
2008
2009bool ScriptInterpreterPythonImpl::GenerateTypeScriptFunction(
2010 const char *oneliner, std::string &output, const void *name_token) {
2011 StringList input;
2012 input.SplitIntoLines(oneliner, strlen(oneliner));
2013 return GenerateTypeScriptFunction(input, output, name_token);
2014}
2015
2016bool ScriptInterpreterPythonImpl::GenerateTypeSynthClass(
2017 const char *oneliner, std::string &output, const void *name_token) {
2018 StringList input;
2019 input.SplitIntoLines(oneliner, strlen(oneliner));
2020 return GenerateTypeSynthClass(input, output, name_token);
2021}
2022
2023Status ScriptInterpreterPythonImpl::GenerateBreakpointCommandCallbackData(
2024 StringList &user_input, std::string &output, bool has_extra_args,
2025 bool is_callback) {
2026 static uint32_t num_created_functions = 0;
2027 user_input.RemoveBlankLines();
2028 StreamString sstr;
2029 Status error;
2030 if (user_input.GetSize() == 0) {
2031 error.SetErrorString("No input data.");
2032 return error;
2033 }
2034
2035 std::string auto_generated_function_name(GenerateUniqueName(
2036 "lldb_autogen_python_bp_callback_func_", num_created_functions));
2037 if (has_extra_args)
2038 sstr.Printf("def %s (frame, bp_loc, extra_args, internal_dict):",
2039 auto_generated_function_name.c_str());
2040 else
2041 sstr.Printf("def %s (frame, bp_loc, internal_dict):",
2042 auto_generated_function_name.c_str());
2043
2044 error = GenerateFunction(sstr.GetData(), user_input, is_callback);
2045 if (!error.Success())
2046 return error;
2047
2048 // Store the name of the auto-generated function to be called.
2049 output.assign(auto_generated_function_name);
2050 return error;
2051}
2052
2053bool ScriptInterpreterPythonImpl::GenerateWatchpointCommandCallbackData(
2054 StringList &user_input, std::string &output, bool is_callback) {
2055 static uint32_t num_created_functions = 0;
2056 user_input.RemoveBlankLines();
2057 StreamString sstr;
2058
2059 if (user_input.GetSize() == 0)
2060 return false;
2061
2062 std::string auto_generated_function_name(GenerateUniqueName(
2063 "lldb_autogen_python_wp_callback_func_", num_created_functions));
2064 sstr.Printf("def %s (frame, wp, internal_dict):",
2065 auto_generated_function_name.c_str());
2066
2067 if (!GenerateFunction(sstr.GetData(), user_input, is_callback).Success())
2068 return false;
2069
2070 // Store the name of the auto-generated function to be called.
2071 output.assign(auto_generated_function_name);
2072 return true;
2073}
2074
2075bool ScriptInterpreterPythonImpl::GetScriptedSummary(
2076 const char *python_function_name, lldb::ValueObjectSP valobj,
2077 StructuredData::ObjectSP &callee_wrapper_sp,
2078 const TypeSummaryOptions &options, std::string &retval) {
2079
2080 LLDB_SCOPED_TIMER()static ::lldb_private::Timer::Category _cat(__PRETTY_FUNCTION__
); ::lldb_private::Timer _scoped_timer(_cat, "%s", __PRETTY_FUNCTION__
)
;
2081
2082 if (!valobj.get()) {
2083 retval.assign("<no object>");
2084 return false;
2085 }
2086
2087 void *old_callee = nullptr;
2088 StructuredData::Generic *generic = nullptr;
2089 if (callee_wrapper_sp) {
2090 generic = callee_wrapper_sp->GetAsGeneric();
2091 if (generic)
2092 old_callee = generic->GetValue();
2093 }
2094 void *new_callee = old_callee;
2095
2096 bool ret_val;
2097 if (python_function_name && *python_function_name) {
2098 {
2099 Locker py_lock(this, Locker::AcquireLock | Locker::InitSession |
2100 Locker::NoSTDIN);
2101 {
2102 TypeSummaryOptionsSP options_sp(new TypeSummaryOptions(options));
2103
2104 static Timer::Category func_cat("LLDBSwigPythonCallTypeScript");
2105 Timer scoped_timer(func_cat, "LLDBSwigPythonCallTypeScript");
2106 ret_val = LLDBSwigPythonCallTypeScript(
2107 python_function_name, GetSessionDictionary().get(), valobj,
2108 &new_callee, options_sp, retval);
2109 }
2110 }
2111 } else {
2112 retval.assign("<no function name>");
2113 return false;
2114 }
2115
2116 if (new_callee && old_callee != new_callee) {
2117 Locker py_lock(this,
2118 Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
2119 callee_wrapper_sp = std::make_shared<StructuredPythonObject>(
2120 PythonObject(PyRefType::Borrowed, static_cast<PyObject *>(new_callee)));
2121 }
2122
2123 return ret_val;
2124}
2125
2126bool ScriptInterpreterPythonImpl::FormatterCallbackFunction(
2127 const char *python_function_name, TypeImplSP type_impl_sp) {
2128 Locker py_lock(this,
2129 Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
2130 return LLDBSwigPythonFormatterCallbackFunction(
2131 python_function_name, m_dictionary_name.c_str(), type_impl_sp);
2132}
2133
2134bool ScriptInterpreterPythonImpl::BreakpointCallbackFunction(
2135 void *baton, StoppointCallbackContext *context, user_id_t break_id,
2136 user_id_t break_loc_id) {
2137 CommandDataPython *bp_option_data = (CommandDataPython *)baton;
2138 const char *python_function_name = bp_option_data->script_source.c_str();
2139
2140 if (!context)
2141 return true;
2142
2143 ExecutionContext exe_ctx(context->exe_ctx_ref);
2144 Target *target = exe_ctx.GetTargetPtr();
2145
2146 if (!target)
2147 return true;
2148
2149 Debugger &debugger = target->GetDebugger();
2150 ScriptInterpreterPythonImpl *python_interpreter =
2151 GetPythonInterpreter(debugger);
2152
2153 if (!python_interpreter)
2154 return true;
2155
2156 if (python_function_name && python_function_name[0]) {
2157 const StackFrameSP stop_frame_sp(exe_ctx.GetFrameSP());
2158 BreakpointSP breakpoint_sp = target->GetBreakpointByID(break_id);
2159 if (breakpoint_sp) {
2160 const BreakpointLocationSP bp_loc_sp(
2161 breakpoint_sp->FindLocationByID(break_loc_id));
2162
2163 if (stop_frame_sp && bp_loc_sp) {
2164 bool ret_val = true;
2165 {
2166 Locker py_lock(python_interpreter, Locker::AcquireLock |
2167 Locker::InitSession |
2168 Locker::NoSTDIN);
2169 Expected<bool> maybe_ret_val =
2170 LLDBSwigPythonBreakpointCallbackFunction(
2171 python_function_name,
2172 python_interpreter->m_dictionary_name.c_str(), stop_frame_sp,
2173 bp_loc_sp, bp_option_data->m_extra_args);
2174
2175 if (!maybe_ret_val) {
2176
2177 llvm::handleAllErrors(
2178 maybe_ret_val.takeError(),
2179 [&](PythonException &E) {
2180 debugger.GetErrorStream() << E.ReadBacktrace();
2181 },
2182 [&](const llvm::ErrorInfoBase &E) {
2183 debugger.GetErrorStream() << E.message();
2184 });
2185
2186 } else {
2187 ret_val = maybe_ret_val.get();
2188 }
2189 }
2190 return ret_val;
2191 }
2192 }
2193 }
2194 // We currently always true so we stop in case anything goes wrong when
2195 // trying to call the script function
2196 return true;
2197}
2198
2199bool ScriptInterpreterPythonImpl::WatchpointCallbackFunction(
2200 void *baton, StoppointCallbackContext *context, user_id_t watch_id) {
2201 WatchpointOptions::CommandData *wp_option_data =
2202 (WatchpointOptions::CommandData *)baton;
2203 const char *python_function_name = wp_option_data->script_source.c_str();
2204
2205 if (!context)
2206 return true;
2207
2208 ExecutionContext exe_ctx(context->exe_ctx_ref);
2209 Target *target = exe_ctx.GetTargetPtr();
2210
2211 if (!target)
2212 return true;
2213
2214 Debugger &debugger = target->GetDebugger();
2215 ScriptInterpreterPythonImpl *python_interpreter =
2216 GetPythonInterpreter(debugger);
2217
2218 if (!python_interpreter)
2219 return true;
2220
2221 if (python_function_name && python_function_name[0]) {
2222 const StackFrameSP stop_frame_sp(exe_ctx.GetFrameSP());
2223 WatchpointSP wp_sp = target->GetWatchpointList().FindByID(watch_id);
2224 if (wp_sp) {
2225 if (stop_frame_sp && wp_sp) {
2226 bool ret_val = true;
2227 {
2228 Locker py_lock(python_interpreter, Locker::AcquireLock |
2229 Locker::InitSession |
2230 Locker::NoSTDIN);
2231 ret_val = LLDBSwigPythonWatchpointCallbackFunction(
2232 python_function_name,
2233 python_interpreter->m_dictionary_name.c_str(), stop_frame_sp,
2234 wp_sp);
2235 }
2236 return ret_val;
2237 }
2238 }
2239 }
2240 // We currently always true so we stop in case anything goes wrong when
2241 // trying to call the script function
2242 return true;
2243}
2244
2245size_t ScriptInterpreterPythonImpl::CalculateNumChildren(
2246 const StructuredData::ObjectSP &implementor_sp, uint32_t max) {
2247 if (!implementor_sp)
2248 return 0;
2249 StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
2250 if (!generic)
2251 return 0;
2252 auto *implementor = static_cast<PyObject *>(generic->GetValue());
2253 if (!implementor)
2254 return 0;
2255
2256 size_t ret_val = 0;
2257
2258 {
2259 Locker py_lock(this,
2260 Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
2261 ret_val = LLDBSwigPython_CalculateNumChildren(implementor, max);
2262 }
2263
2264 return ret_val;
2265}
2266
2267lldb::ValueObjectSP ScriptInterpreterPythonImpl::GetChildAtIndex(
2268 const StructuredData::ObjectSP &implementor_sp, uint32_t idx) {
2269 if (!implementor_sp)
2270 return lldb::ValueObjectSP();
2271
2272 StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
2273 if (!generic)
2274 return lldb::ValueObjectSP();
2275 auto *implementor = static_cast<PyObject *>(generic->GetValue());
2276 if (!implementor)
2277 return lldb::ValueObjectSP();
2278
2279 lldb::ValueObjectSP ret_val;
2280 {
2281 Locker py_lock(this,
2282 Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
2283 PyObject *child_ptr = LLDBSwigPython_GetChildAtIndex(implementor, idx);
2284 if (child_ptr != nullptr && child_ptr != Py_None(&_Py_NoneStruct)) {
2285 lldb::SBValue *sb_value_ptr =
2286 (lldb::SBValue *)LLDBSWIGPython_CastPyObjectToSBValue(child_ptr);
2287 if (sb_value_ptr == nullptr)
2288 Py_XDECREF(child_ptr)_Py_XDECREF(((PyObject*)(child_ptr)));
2289 else
2290 ret_val = LLDBSWIGPython_GetValueObjectSPFromSBValue(sb_value_ptr);
2291 } else {
2292 Py_XDECREF(child_ptr)_Py_XDECREF(((PyObject*)(child_ptr)));
2293 }
2294 }
2295
2296 return ret_val;
2297}
2298
2299int ScriptInterpreterPythonImpl::GetIndexOfChildWithName(
2300 const StructuredData::ObjectSP &implementor_sp, const char *child_name) {
2301 if (!implementor_sp)
2302 return UINT32_MAX(4294967295U);
2303
2304 StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
2305 if (!generic)
2306 return UINT32_MAX(4294967295U);
2307 auto *implementor = static_cast<PyObject *>(generic->GetValue());
2308 if (!implementor)
2309 return UINT32_MAX(4294967295U);
2310
2311 int ret_val = UINT32_MAX(4294967295U);
2312
2313 {
2314 Locker py_lock(this,
2315 Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
2316 ret_val = LLDBSwigPython_GetIndexOfChildWithName(implementor, child_name);
2317 }
2318
2319 return ret_val;
2320}
2321
2322bool ScriptInterpreterPythonImpl::UpdateSynthProviderInstance(
2323 const StructuredData::ObjectSP &implementor_sp) {
2324 bool ret_val = false;
2325
2326 if (!implementor_sp)
2327 return ret_val;
2328
2329 StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
2330 if (!generic)
2331 return ret_val;
2332 auto *implementor = static_cast<PyObject *>(generic->GetValue());
2333 if (!implementor)
2334 return ret_val;
2335
2336 {
2337 Locker py_lock(this,
2338 Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
2339 ret_val = LLDBSwigPython_UpdateSynthProviderInstance(implementor);
2340 }
2341
2342 return ret_val;
2343}
2344
2345bool ScriptInterpreterPythonImpl::MightHaveChildrenSynthProviderInstance(
2346 const StructuredData::ObjectSP &implementor_sp) {
2347 bool ret_val = false;
2348
2349 if (!implementor_sp)
2350 return ret_val;
2351
2352 StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
2353 if (!generic)
2354 return ret_val;
2355 auto *implementor = static_cast<PyObject *>(generic->GetValue());
2356 if (!implementor)
2357 return ret_val;
2358
2359 {
2360 Locker py_lock(this,
2361 Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
2362 ret_val =
2363 LLDBSwigPython_MightHaveChildrenSynthProviderInstance(implementor);
2364 }
2365
2366 return ret_val;
2367}
2368
2369lldb::ValueObjectSP ScriptInterpreterPythonImpl::GetSyntheticValue(
2370 const StructuredData::ObjectSP &implementor_sp) {
2371 lldb::ValueObjectSP ret_val(nullptr);
2372
2373 if (!implementor_sp)
2374 return ret_val;
2375
2376 StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
2377 if (!generic)
2378 return ret_val;
2379 auto *implementor = static_cast<PyObject *>(generic->GetValue());
2380 if (!implementor)
2381 return ret_val;
2382
2383 {
2384 Locker py_lock(this,
2385 Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
2386 PyObject *child_ptr =
2387 LLDBSwigPython_GetValueSynthProviderInstance(implementor);
2388 if (child_ptr != nullptr && child_ptr != Py_None(&_Py_NoneStruct)) {
2389 lldb::SBValue *sb_value_ptr =
2390 (lldb::SBValue *)LLDBSWIGPython_CastPyObjectToSBValue(child_ptr);
2391 if (sb_value_ptr == nullptr)
2392 Py_XDECREF(child_ptr)_Py_XDECREF(((PyObject*)(child_ptr)));
2393 else
2394 ret_val = LLDBSWIGPython_GetValueObjectSPFromSBValue(sb_value_ptr);
2395 } else {
2396 Py_XDECREF(child_ptr)_Py_XDECREF(((PyObject*)(child_ptr)));
2397 }
2398 }
2399
2400 return ret_val;
2401}
2402
2403ConstString ScriptInterpreterPythonImpl::GetSyntheticTypeName(
2404 const StructuredData::ObjectSP &implementor_sp) {
2405 Locker py_lock(this,
2406 Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
2407
2408 if (!implementor_sp)
2409 return {};
2410
2411 StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
2412 if (!generic)
2413 return {};
2414
2415 PythonObject implementor(PyRefType::Borrowed,
2416 (PyObject *)generic->GetValue());
2417 if (!implementor.IsAllocated())
2418 return {};
2419
2420 llvm::Expected<PythonObject> expected_py_return =
2421 implementor.CallMethod("get_type_name");
2422
2423 if (!expected_py_return) {
2424 llvm::consumeError(expected_py_return.takeError());
2425 return {};
2426 }
2427
2428 PythonObject py_return = std::move(expected_py_return.get());
2429
2430 ConstString ret_val;
2431 bool got_string = false;
2432 std::string buffer;
2433
2434 if (py_return.IsAllocated() && PythonString::Check(py_return.get())) {
2435 PythonString py_string(PyRefType::Borrowed, py_return.get());
2436 llvm::StringRef return_data(py_string.GetString());
2437 if (!return_data.empty()) {
2438 buffer.assign(return_data.data(), return_data.size());
2439 got_string = true;
2440 }
2441 }
2442
2443 if (got_string)
2444 ret_val.SetCStringWithLength(buffer.c_str(), buffer.size());
2445
2446 return ret_val;
2447}
2448
2449bool ScriptInterpreterPythonImpl::RunScriptFormatKeyword(
2450 const char *impl_function, Process *process, std::string &output,
2451 Status &error) {
2452 bool ret_val;
2453 if (!process) {
2454 error.SetErrorString("no process");
2455 return false;
2456 }
2457 if (!impl_function || !impl_function[0]) {
2458 error.SetErrorString("no function to execute");
2459 return false;
2460 }
2461
2462 {
2463 Locker py_lock(this,
2464 Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
2465 ret_val = LLDBSWIGPythonRunScriptKeywordProcess(
2466 impl_function, m_dictionary_name.c_str(), process->shared_from_this(),
2467 output);
2468 if (!ret_val)
2469 error.SetErrorString("python script evaluation failed");
2470 }
2471 return ret_val;
2472}
2473
2474bool ScriptInterpreterPythonImpl::RunScriptFormatKeyword(
2475 const char *impl_function, Thread *thread, std::string &output,
2476 Status &error) {
2477 if (!thread) {
2478 error.SetErrorString("no thread");
2479 return false;
2480 }
2481 if (!impl_function || !impl_function[0]) {
2482 error.SetErrorString("no function to execute");
2483 return false;
2484 }
2485
2486 Locker py_lock(this,
2487 Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
2488 if (std::optional<std::string> result = LLDBSWIGPythonRunScriptKeywordThread(
2489 impl_function, m_dictionary_name.c_str(),
2490 thread->shared_from_this())) {
2491 output = std::move(*result);
2492 return true;
2493 }
2494 error.SetErrorString("python script evaluation failed");
2495 return false;
2496}
2497
2498bool ScriptInterpreterPythonImpl::RunScriptFormatKeyword(
2499 const char *impl_function, Target *target, std::string &output,
2500 Status &error) {
2501 bool ret_val;
2502 if (!target) {
2503 error.SetErrorString("no thread");
2504 return false;
2505 }
2506 if (!impl_function || !impl_function[0]) {
2507 error.SetErrorString("no function to execute");
2508 return false;
2509 }
2510
2511 {
2512 TargetSP target_sp(target->shared_from_this());
2513 Locker py_lock(this,
2514 Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
2515 ret_val = LLDBSWIGPythonRunScriptKeywordTarget(
2516 impl_function, m_dictionary_name.c_str(), target_sp, output);
2517 if (!ret_val)
2518 error.SetErrorString("python script evaluation failed");
2519 }
2520 return ret_val;
2521}
2522
2523bool ScriptInterpreterPythonImpl::RunScriptFormatKeyword(
2524 const char *impl_function, StackFrame *frame, std::string &output,
2525 Status &error) {
2526 if (!frame) {
2527 error.SetErrorString("no frame");
2528 return false;
2529 }
2530 if (!impl_function || !impl_function[0]) {
2531 error.SetErrorString("no function to execute");
2532 return false;
2533 }
2534
2535 Locker py_lock(this,
2536 Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
2537 if (std::optional<std::string> result = LLDBSWIGPythonRunScriptKeywordFrame(
2538 impl_function, m_dictionary_name.c_str(),
2539 frame->shared_from_this())) {
2540 output = std::move(*result);
2541 return true;
2542 }
2543 error.SetErrorString("python script evaluation failed");
2544 return false;
2545}
2546
2547bool ScriptInterpreterPythonImpl::RunScriptFormatKeyword(
2548 const char *impl_function, ValueObject *value, std::string &output,
2549 Status &error) {
2550 bool ret_val;
2551 if (!value) {
2552 error.SetErrorString("no value");
2553 return false;
2554 }
2555 if (!impl_function || !impl_function[0]) {
2556 error.SetErrorString("no function to execute");
2557 return false;
2558 }
2559
2560 {
2561 Locker py_lock(this,
2562 Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
2563 ret_val = LLDBSWIGPythonRunScriptKeywordValue(
2564 impl_function, m_dictionary_name.c_str(), value->GetSP(), output);
2565 if (!ret_val)
2566 error.SetErrorString("python script evaluation failed");
2567 }
2568 return ret_val;
2569}
2570
2571uint64_t replace_all(std::string &str, const std::string &oldStr,
2572 const std::string &newStr) {
2573 size_t pos = 0;
2574 uint64_t matches = 0;
2575 while ((pos = str.find(oldStr, pos)) != std::string::npos) {
2576 matches++;
2577 str.replace(pos, oldStr.length(), newStr);
2578 pos += newStr.length();
2579 }
2580 return matches;
2581}
2582
2583bool ScriptInterpreterPythonImpl::LoadScriptingModule(
2584 const char *pathname, const LoadScriptOptions &options,
2585 lldb_private::Status &error, StructuredData::ObjectSP *module_sp,
2586 FileSpec extra_search_dir) {
2587 namespace fs = llvm::sys::fs;
2588 namespace path = llvm::sys::path;
2589
2590 ExecuteScriptOptions exc_options = ExecuteScriptOptions()
2591 .SetEnableIO(!options.GetSilent())
2592 .SetSetLLDBGlobals(false);
2593
2594 if (!pathname || !pathname[0]) {
2595 error.SetErrorString("empty path");
2596 return false;
2597 }
2598
2599 llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>>
2600 io_redirect_or_error = ScriptInterpreterIORedirect::Create(
2601 exc_options.GetEnableIO(), m_debugger, /*result=*/nullptr);
2602
2603 if (!io_redirect_or_error) {
2604 error = io_redirect_or_error.takeError();
2605 return false;
2606 }
2607
2608 ScriptInterpreterIORedirect &io_redirect = **io_redirect_or_error;
2609
2610 // Before executing Python code, lock the GIL.
2611 Locker py_lock(this,
2612 Locker::AcquireLock |
2613 (options.GetInitSession() ? Locker::InitSession : 0) |
2614 Locker::NoSTDIN,
2615 Locker::FreeAcquiredLock |
2616 (options.GetInitSession() ? Locker::TearDownSession : 0),
2617 io_redirect.GetInputFile(), io_redirect.GetOutputFile(),
2618 io_redirect.GetErrorFile());
2619
2620 auto ExtendSysPath = [&](std::string directory) -> llvm::Error {
2621 if (directory.empty()) {
2622 return llvm::make_error<llvm::StringError>(
2623 "invalid directory name", llvm::inconvertibleErrorCode());
2624 }
2625
2626 replace_all(directory, "\\", "\\\\");
2627 replace_all(directory, "'", "\\'");
2628
2629 // Make sure that Python has "directory" in the search path.
2630 StreamString command_stream;
2631 command_stream.Printf("if not (sys.path.__contains__('%s')):\n "
2632 "sys.path.insert(1,'%s');\n\n",
2633 directory.c_str(), directory.c_str());
2634 bool syspath_retval =
2635 ExecuteMultipleLines(command_stream.GetData(), exc_options).Success();
2636 if (!syspath_retval) {
2637 return llvm::make_error<llvm::StringError>(
2638 "Python sys.path handling failed", llvm::inconvertibleErrorCode());
2639 }
2640
2641 return llvm::Error::success();
2642 };
2643
2644 std::string module_name(pathname);
2645 bool possible_package = false;
2646
2647 if (extra_search_dir) {
2648 if (llvm::Error e = ExtendSysPath(extra_search_dir.GetPath())) {
2649 error = std::move(e);
2650 return false;
2651 }
2652 } else {
2653 FileSpec module_file(pathname);
2654 FileSystem::Instance().Resolve(module_file);
2655
2656 fs::file_status st;
2657 std::error_code ec = status(module_file.GetPath(), st);
2658
2659 if (ec || st.type() == fs::file_type::status_error ||
2660 st.type() == fs::file_type::type_unknown ||
2661 st.type() == fs::file_type::file_not_found) {
2662 // if not a valid file of any sort, check if it might be a filename still
2663 // dot can't be used but / and \ can, and if either is found, reject
2664 if (strchr(pathname, '\\') || strchr(pathname, '/')) {
2665 error.SetErrorStringWithFormatv("invalid pathname '{0}'", pathname);
2666 return false;
2667 }
2668 // Not a filename, probably a package of some sort, let it go through.
2669 possible_package = true;
2670 } else if (is_directory(st) || is_regular_file(st)) {
2671 if (module_file.GetDirectory().IsEmpty()) {
2672 error.SetErrorStringWithFormatv("invalid directory name '{0}'", pathname);
2673 return false;
2674 }
2675 if (llvm::Error e =
2676 ExtendSysPath(module_file.GetDirectory().GetCString())) {
2677 error = std::move(e);
2678 return false;
2679 }
2680 module_name = module_file.GetFilename().GetCString();
2681 } else {
2682 error.SetErrorString("no known way to import this module specification");
2683 return false;
2684 }
2685 }
2686
2687 // Strip .py or .pyc extension
2688 llvm::StringRef extension = llvm::sys::path::extension(module_name);
2689 if (!extension.empty()) {
2690 if (extension == ".py")
2691 module_name.resize(module_name.length() - 3);
2692 else if (extension == ".pyc")
2693 module_name.resize(module_name.length() - 4);
2694 }
2695
2696 if (!possible_package && module_name.find('.') != llvm::StringRef::npos) {
2697 error.SetErrorStringWithFormat(
2698 "Python does not allow dots in module names: %s", module_name.c_str());
2699 return false;
2700 }
2701
2702 if (module_name.find('-') != llvm::StringRef::npos) {
2703 error.SetErrorStringWithFormat(
2704 "Python discourages dashes in module names: %s", module_name.c_str());
2705 return false;
2706 }
2707
2708 // Check if the module is already imported.
2709 StreamString command_stream;
2710 command_stream.Clear();
2711 command_stream.Printf("sys.modules.__contains__('%s')", module_name.c_str());
2712 bool does_contain = false;
2713 // This call will succeed if the module was ever imported in any Debugger in
2714 // the lifetime of the process in which this LLDB framework is living.
2715 const bool does_contain_executed = ExecuteOneLineWithReturn(
2716 command_stream.GetData(),
2717 ScriptInterpreterPythonImpl::eScriptReturnTypeBool, &does_contain, exc_options);
2718
2719 const bool was_imported_globally = does_contain_executed && does_contain;
2720 const bool was_imported_locally =
2721 GetSessionDictionary()
2722 .GetItemForKey(PythonString(module_name))
2723 .IsAllocated();
2724
2725 // now actually do the import
2726 command_stream.Clear();
2727
2728 if (was_imported_globally || was_imported_locally) {
2729 if (!was_imported_locally)
2730 command_stream.Printf("import %s ; reload_module(%s)",
2731 module_name.c_str(), module_name.c_str());
2732 else
2733 command_stream.Printf("reload_module(%s)", module_name.c_str());
2734 } else
2735 command_stream.Printf("import %s", module_name.c_str());
2736
2737 error = ExecuteMultipleLines(command_stream.GetData(), exc_options);
2738 if (error.Fail())
2739 return false;
2740
2741 // if we are here, everything worked
2742 // call __lldb_init_module(debugger,dict)
2743 if (!LLDBSwigPythonCallModuleInit(module_name.c_str(),
2744 m_dictionary_name.c_str(),
2745 m_debugger.shared_from_this())) {
2746 error.SetErrorString("calling __lldb_init_module failed");
2747 return false;
2748 }
2749
2750 if (module_sp) {
2751 // everything went just great, now set the module object
2752 command_stream.Clear();
2753 command_stream.Printf("%s", module_name.c_str());
2754 void *module_pyobj = nullptr;
2755 if (ExecuteOneLineWithReturn(
2756 command_stream.GetData(),
2757 ScriptInterpreter::eScriptReturnTypeOpaqueObject, &module_pyobj,
2758 exc_options) &&
2759 module_pyobj)
2760 *module_sp = std::make_shared<StructuredPythonObject>(PythonObject(
2761 PyRefType::Owned, static_cast<PyObject *>(module_pyobj)));
2762 }
2763
2764 return true;
2765}
2766
2767bool ScriptInterpreterPythonImpl::IsReservedWord(const char *word) {
2768 if (!word || !word[0])
2769 return false;
2770
2771 llvm::StringRef word_sr(word);
2772
2773 // filter out a few characters that would just confuse us and that are
2774 // clearly not keyword material anyway
2775 if (word_sr.find('"') != llvm::StringRef::npos ||
2776 word_sr.find('\'') != llvm::StringRef::npos)
2777 return false;
2778
2779 StreamString command_stream;
2780 command_stream.Printf("keyword.iskeyword('%s')", word);
2781 bool result;
2782 ExecuteScriptOptions options;
2783 options.SetEnableIO(false);
2784 options.SetMaskoutErrors(true);
2785 options.SetSetLLDBGlobals(false);
2786 if (ExecuteOneLineWithReturn(command_stream.GetData(),
2787 ScriptInterpreter::eScriptReturnTypeBool,
2788 &result, options))
2789 return result;
2790 return false;
2791}
2792
2793ScriptInterpreterPythonImpl::SynchronicityHandler::SynchronicityHandler(
2794 lldb::DebuggerSP debugger_sp, ScriptedCommandSynchronicity synchro)
2795 : m_debugger_sp(debugger_sp), m_synch_wanted(synchro),
2796 m_old_asynch(debugger_sp->GetAsyncExecution()) {
2797 if (m_synch_wanted == eScriptedCommandSynchronicitySynchronous)
2798 m_debugger_sp->SetAsyncExecution(false);
2799 else if (m_synch_wanted == eScriptedCommandSynchronicityAsynchronous)
2800 m_debugger_sp->SetAsyncExecution(true);
2801}
2802
2803ScriptInterpreterPythonImpl::SynchronicityHandler::~SynchronicityHandler() {
2804 if (m_synch_wanted != eScriptedCommandSynchronicityCurrentValue)
2805 m_debugger_sp->SetAsyncExecution(m_old_asynch);
2806}
2807
2808bool ScriptInterpreterPythonImpl::RunScriptBasedCommand(
2809 const char *impl_function, llvm::StringRef args,
2810 ScriptedCommandSynchronicity synchronicity,
2811 lldb_private::CommandReturnObject &cmd_retobj, Status &error,
2812 const lldb_private::ExecutionContext &exe_ctx) {
2813 if (!impl_function) {
2814 error.SetErrorString("no function to execute");
2815 return false;
2816 }
2817
2818 lldb::DebuggerSP debugger_sp = m_debugger.shared_from_this();
2819 lldb::ExecutionContextRefSP exe_ctx_ref_sp(new ExecutionContextRef(exe_ctx));
2820
2821 if (!debugger_sp.get()) {
2822 error.SetErrorString("invalid Debugger pointer");
2823 return false;
2824 }
2825
2826 bool ret_val = false;
2827
2828 std::string err_msg;
2829
2830 {
2831 Locker py_lock(this,
2832 Locker::AcquireLock | Locker::InitSession |
2833 (cmd_retobj.GetInteractive() ? 0 : Locker::NoSTDIN),
2834 Locker::FreeLock | Locker::TearDownSession);
2835
2836 SynchronicityHandler synch_handler(debugger_sp, synchronicity);
2837
2838 std::string args_str = args.str();
2839 ret_val = LLDBSwigPythonCallCommand(
2840 impl_function, m_dictionary_name.c_str(), debugger_sp, args_str.c_str(),
2841 cmd_retobj, exe_ctx_ref_sp);
2842 }
2843
2844 if (!ret_val)
2845 error.SetErrorString("unable to execute script function");
2846 else if (cmd_retobj.GetStatus() == eReturnStatusFailed)
2847 return false;
2848
2849 error.Clear();
2850 return ret_val;
2851}
2852
2853bool ScriptInterpreterPythonImpl::RunScriptBasedCommand(
2854 StructuredData::GenericSP impl_obj_sp, llvm::StringRef args,
2855 ScriptedCommandSynchronicity synchronicity,
2856 lldb_private::CommandReturnObject &cmd_retobj, Status &error,
2857 const lldb_private::ExecutionContext &exe_ctx) {
2858 if (!impl_obj_sp || !impl_obj_sp->IsValid()) {
2859 error.SetErrorString("no function to execute");
2860 return false;
2861 }
2862
2863 lldb::DebuggerSP debugger_sp = m_debugger.shared_from_this();
2864 lldb::ExecutionContextRefSP exe_ctx_ref_sp(new ExecutionContextRef(exe_ctx));
2865
2866 if (!debugger_sp.get()) {
2867 error.SetErrorString("invalid Debugger pointer");
2868 return false;
2869 }
2870
2871 bool ret_val = false;
2872
2873 std::string err_msg;
2874
2875 {
2876 Locker py_lock(this,
2877 Locker::AcquireLock | Locker::InitSession |
2878 (cmd_retobj.GetInteractive() ? 0 : Locker::NoSTDIN),
2879 Locker::FreeLock | Locker::TearDownSession);
2880
2881 SynchronicityHandler synch_handler(debugger_sp, synchronicity);
2882
2883 std::string args_str = args.str();
2884 ret_val = LLDBSwigPythonCallCommandObject(
2885 static_cast<PyObject *>(impl_obj_sp->GetValue()), debugger_sp,
2886 args_str.c_str(), cmd_retobj, exe_ctx_ref_sp);
2887 }
2888
2889 if (!ret_val)
2890 error.SetErrorString("unable to execute script function");
2891 else if (cmd_retobj.GetStatus() == eReturnStatusFailed)
2892 return false;
2893
2894 error.Clear();
2895 return ret_val;
2896}
2897
2898/// In Python, a special attribute __doc__ contains the docstring for an object
2899/// (function, method, class, ...) if any is defined Otherwise, the attribute's
2900/// value is None.
2901bool ScriptInterpreterPythonImpl::GetDocumentationForItem(const char *item,
2902 std::string &dest) {
2903 dest.clear();
2904
2905 if (!item || !*item)
2906 return false;
2907
2908 std::string command(item);
2909 command += ".__doc__";
2910
2911 // Python is going to point this to valid data if ExecuteOneLineWithReturn
2912 // returns successfully.
2913 char *result_ptr = nullptr;
2914
2915 if (ExecuteOneLineWithReturn(
2916 command, ScriptInterpreter::eScriptReturnTypeCharStrOrNone,
2917 &result_ptr,
2918 ExecuteScriptOptions().SetEnableIO(false))) {
2919 if (result_ptr)
2920 dest.assign(result_ptr);
2921 return true;
2922 }
2923
2924 StreamString str_stream;
2925 str_stream << "Function " << item
2926 << " was not found. Containing module might be missing.";
2927 dest = std::string(str_stream.GetString());
2928
2929 return false;
2930}
2931
2932bool ScriptInterpreterPythonImpl::GetShortHelpForCommandObject(
2933 StructuredData::GenericSP cmd_obj_sp, std::string &dest) {
2934 dest.clear();
2935
2936 Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
2937
2938 if (!cmd_obj_sp)
2939 return false;
2940
2941 PythonObject implementor(PyRefType::Borrowed,
2942 (PyObject *)cmd_obj_sp->GetValue());
2943
2944 if (!implementor.IsAllocated())
2945 return false;
2946
2947 llvm::Expected<PythonObject> expected_py_return =
2948 implementor.CallMethod("get_short_help");
2949
2950 if (!expected_py_return) {
2951 llvm::consumeError(expected_py_return.takeError());
2952 return false;
2953 }
2954
2955 PythonObject py_return = std::move(expected_py_return.get());
2956
2957 if (py_return.IsAllocated() && PythonString::Check(py_return.get())) {
2958 PythonString py_string(PyRefType::Borrowed, py_return.get());
2959 llvm::StringRef return_data(py_string.GetString());
2960 dest.assign(return_data.data(), return_data.size());
2961 return true;
2962 }
2963
2964 return false;
2965}
2966
2967uint32_t ScriptInterpreterPythonImpl::GetFlagsForCommandObject(
2968 StructuredData::GenericSP cmd_obj_sp) {
2969 uint32_t result = 0;
2970
2971 Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
2972
2973 static char callee_name[] = "get_flags";
2974
2975 if (!cmd_obj_sp)
2976 return result;
2977
2978 PythonObject implementor(PyRefType::Borrowed,
2979 (PyObject *)cmd_obj_sp->GetValue());
2980
2981 if (!implementor.IsAllocated())
2982 return result;
2983
2984 PythonObject pmeth(PyRefType::Owned,
2985 PyObject_GetAttrString(implementor.get(), callee_name));
2986
2987 if (PyErr_Occurred())
2988 PyErr_Clear();
2989
2990 if (!pmeth.IsAllocated())
2991 return result;
2992
2993 if (PyCallable_Check(pmeth.get()) == 0) {
2994 if (PyErr_Occurred())
2995 PyErr_Clear();
2996 return result;
2997 }
2998
2999 if (PyErr_Occurred())
3000 PyErr_Clear();
3001
3002 long long py_return = unwrapOrSetPythonException(
3003 As<long long>(implementor.CallMethod(callee_name)));
3004
3005 // if it fails, print the error but otherwise go on
3006 if (PyErr_Occurred()) {
3007 PyErr_Print();
3008 PyErr_Clear();
3009 } else {
3010 result = py_return;
3011 }
3012
3013 return result;
3014}
3015
3016bool ScriptInterpreterPythonImpl::GetLongHelpForCommandObject(
3017 StructuredData::GenericSP cmd_obj_sp, std::string &dest) {
3018 dest.clear();
3019
3020 Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
3021
3022 if (!cmd_obj_sp)
3023 return false;
3024
3025 PythonObject implementor(PyRefType::Borrowed,
3026 (PyObject *)cmd_obj_sp->GetValue());
3027
3028 if (!implementor.IsAllocated())
3029 return false;
3030
3031 llvm::Expected<PythonObject> expected_py_return =
3032 implementor.CallMethod("get_long_help");
3033
3034 if (!expected_py_return) {
3035 llvm::consumeError(expected_py_return.takeError());
3036 return false;
3037 }
3038
3039 PythonObject py_return = std::move(expected_py_return.get());
3040
3041 bool got_string = false;
3042 if (py_return.IsAllocated() && PythonString::Check(py_return.get())) {
3043 PythonString str(PyRefType::Borrowed, py_return.get());
3044 llvm::StringRef str_data(str.GetString());
3045 dest.assign(str_data.data(), str_data.size());
3046 got_string = true;
3047 }
3048
3049 return got_string;
3050}
3051
3052std::unique_ptr<ScriptInterpreterLocker>
3053ScriptInterpreterPythonImpl::AcquireInterpreterLock() {
3054 std::unique_ptr<ScriptInterpreterLocker> py_lock(new Locker(
3055 this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN,
3056 Locker::FreeLock | Locker::TearDownSession));
3057 return py_lock;
3058}
3059
3060void ScriptInterpreterPythonImpl::Initialize() {
3061 LLDB_SCOPED_TIMER()static ::lldb_private::Timer::Category _cat(__PRETTY_FUNCTION__
); ::lldb_private::Timer _scoped_timer(_cat, "%s", __PRETTY_FUNCTION__
)
;
3062
3063 // RAII-based initialization which correctly handles multiple-initialization,
3064 // version- specific differences among Python 2 and Python 3, and saving and
3065 // restoring various other pieces of state that can get mucked with during
3066 // initialization.
3067 InitializePythonRAII initialize_guard;
3068
3069 LLDBSwigPyInitPyInit__lldb();
3070
3071 // Update the path python uses to search for modules to include the current
3072 // directory.
3073
3074 PyRun_SimpleString("import sys")PyRun_SimpleStringFlags("import sys", __null);
3075 AddToSysPath(AddLocation::End, ".");
3076
3077 // Don't denormalize paths when calling file_spec.GetPath(). On platforms
3078 // that use a backslash as the path separator, this will result in executing
3079 // python code containing paths with unescaped backslashes. But Python also
3080 // accepts forward slashes, so to make life easier we just use that.
3081 if (FileSpec file_spec = GetPythonDir())
3082 AddToSysPath(AddLocation::Beginning, file_spec.GetPath(false));
3083 if (FileSpec file_spec = HostInfo::GetShlibDir())
3084 AddToSysPath(AddLocation::Beginning, file_spec.GetPath(false));
3085
3086 PyRun_SimpleString("sys.dont_write_bytecode = 1; import "PyRun_SimpleStringFlags("sys.dont_write_bytecode = 1; import "
"lldb.embedded_interpreter; from " "lldb.embedded_interpreter import run_python_interpreter; "
"from lldb.embedded_interpreter import run_one_line", __null
)
3087 "lldb.embedded_interpreter; from "PyRun_SimpleStringFlags("sys.dont_write_bytecode = 1; import "
"lldb.embedded_interpreter; from " "lldb.embedded_interpreter import run_python_interpreter; "
"from lldb.embedded_interpreter import run_one_line", __null
)
3088 "lldb.embedded_interpreter import run_python_interpreter; "PyRun_SimpleStringFlags("sys.dont_write_bytecode = 1; import "
"lldb.embedded_interpreter; from " "lldb.embedded_interpreter import run_python_interpreter; "
"from lldb.embedded_interpreter import run_one_line", __null
)
3089 "from lldb.embedded_interpreter import run_one_line")PyRun_SimpleStringFlags("sys.dont_write_bytecode = 1; import "
"lldb.embedded_interpreter; from " "lldb.embedded_interpreter import run_python_interpreter; "
"from lldb.embedded_interpreter import run_one_line", __null
)
;
3090
3091#if LLDB_USE_PYTHON_SET_INTERRUPT(3 == 3 && 9 >= 2) || (3 > 3)
3092 // Python will not just overwrite its internal SIGINT handler but also the
3093 // one from the process. Backup the current SIGINT handler to prevent that
3094 // Python deletes it.
3095 RestoreSignalHandlerScope save_sigint(SIGINT2);
3096
3097 // Setup a default SIGINT signal handler that works the same way as the
3098 // normal Python REPL signal handler which raises a KeyboardInterrupt.
3099 // Also make sure to not pollute the user's REPL with the signal module nor
3100 // our utility function.
3101 PyRun_SimpleString("def lldb_setup_sigint_handler():\n"PyRun_SimpleStringFlags("def lldb_setup_sigint_handler():\n" " import signal;\n"
" def signal_handler(sig, frame):\n" " raise KeyboardInterrupt()\n"
" signal.signal(signal.SIGINT, signal_handler);\n" "lldb_setup_sigint_handler();\n"
"del lldb_setup_sigint_handler\n", __null)
3102 " import signal;\n"PyRun_SimpleStringFlags("def lldb_setup_sigint_handler():\n" " import signal;\n"
" def signal_handler(sig, frame):\n" " raise KeyboardInterrupt()\n"
" signal.signal(signal.SIGINT, signal_handler);\n" "lldb_setup_sigint_handler();\n"
"del lldb_setup_sigint_handler\n", __null)
3103 " def signal_handler(sig, frame):\n"PyRun_SimpleStringFlags("def lldb_setup_sigint_handler():\n" " import signal;\n"
" def signal_handler(sig, frame):\n" " raise KeyboardInterrupt()\n"
" signal.signal(signal.SIGINT, signal_handler);\n" "lldb_setup_sigint_handler();\n"
"del lldb_setup_sigint_handler\n", __null)
3104 " raise KeyboardInterrupt()\n"PyRun_SimpleStringFlags("def lldb_setup_sigint_handler():\n" " import signal;\n"
" def signal_handler(sig, frame):\n" " raise KeyboardInterrupt()\n"
" signal.signal(signal.SIGINT, signal_handler);\n" "lldb_setup_sigint_handler();\n"
"del lldb_setup_sigint_handler\n", __null)
3105 " signal.signal(signal.SIGINT, signal_handler);\n"PyRun_SimpleStringFlags("def lldb_setup_sigint_handler():\n" " import signal;\n"
" def signal_handler(sig, frame):\n" " raise KeyboardInterrupt()\n"
" signal.signal(signal.SIGINT, signal_handler);\n" "lldb_setup_sigint_handler();\n"
"del lldb_setup_sigint_handler\n", __null)
3106 "lldb_setup_sigint_handler();\n"PyRun_SimpleStringFlags("def lldb_setup_sigint_handler():\n" " import signal;\n"
" def signal_handler(sig, frame):\n" " raise KeyboardInterrupt()\n"
" signal.signal(signal.SIGINT, signal_handler);\n" "lldb_setup_sigint_handler();\n"
"del lldb_setup_sigint_handler\n", __null)
3107 "del lldb_setup_sigint_handler\n")PyRun_SimpleStringFlags("def lldb_setup_sigint_handler():\n" " import signal;\n"
" def signal_handler(sig, frame):\n" " raise KeyboardInterrupt()\n"
" signal.signal(signal.SIGINT, signal_handler);\n" "lldb_setup_sigint_handler();\n"
"del lldb_setup_sigint_handler\n", __null)
;
3108#endif
3109}
3110
3111void ScriptInterpreterPythonImpl::AddToSysPath(AddLocation location,
3112 std::string path) {
3113 std::string path_copy;
3114
3115 std::string statement;
3116 if (location == AddLocation::Beginning) {
3117 statement.assign("sys.path.insert(0,\"");
3118 statement.append(path);
3119 statement.append("\")");
3120 } else {
3121 statement.assign("sys.path.append(\"");
3122 statement.append(path);
3123 statement.append("\")");
3124 }
3125 PyRun_SimpleString(statement.c_str())PyRun_SimpleStringFlags(statement.c_str(), __null);
3126}
3127
3128// We are intentionally NOT calling Py_Finalize here (this would be the logical
3129// place to call it). Calling Py_Finalize here causes test suite runs to seg
3130// fault: The test suite runs in Python. It registers SBDebugger::Terminate to
3131// be called 'at_exit'. When the test suite Python harness finishes up, it
3132// calls Py_Finalize, which calls all the 'at_exit' registered functions.
3133// SBDebugger::Terminate calls Debugger::Terminate, which calls lldb::Terminate,
3134// which calls ScriptInterpreter::Terminate, which calls
3135// ScriptInterpreterPythonImpl::Terminate. So if we call Py_Finalize here, we
3136// end up with Py_Finalize being called from within Py_Finalize, which results
3137// in a seg fault. Since this function only gets called when lldb is shutting
3138// down and going away anyway, the fact that we don't actually call Py_Finalize
3139// should not cause any problems (everything should shut down/go away anyway
3140// when the process exits).
3141//
3142// void ScriptInterpreterPythonImpl::Terminate() { Py_Finalize (); }
3143
3144#endif