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

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