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

source code of lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp