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