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