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