15ffd83dbSDimitry Andric //===-- ScriptInterpreterPython.cpp ---------------------------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 9480093f4SDimitry Andric #include "lldb/Host/Config.h" 10e8d8bef9SDimitry Andric #include "lldb/lldb-enumerations.h" 110b57cec5SDimitry Andric 12480093f4SDimitry Andric #if LLDB_ENABLE_PYTHON 130b57cec5SDimitry Andric 140b57cec5SDimitry Andric // LLDB Python header must be included first 150b57cec5SDimitry Andric #include "lldb-python.h" 160b57cec5SDimitry Andric 170b57cec5SDimitry Andric #include "PythonDataObjects.h" 18c14a5a88SDimitry Andric #include "PythonReadline.h" 19fe6060f1SDimitry Andric #include "SWIGPythonBridge.h" 200b57cec5SDimitry Andric #include "ScriptInterpreterPythonImpl.h" 21bdd1243dSDimitry Andric #include "ScriptedPlatformPythonInterface.h" 22fe6060f1SDimitry Andric #include "ScriptedProcessPythonInterface.h" 23fe6060f1SDimitry Andric 24fe6060f1SDimitry Andric #include "lldb/API/SBError.h" 250b57cec5SDimitry Andric #include "lldb/API/SBFrame.h" 260b57cec5SDimitry Andric #include "lldb/API/SBValue.h" 270b57cec5SDimitry Andric #include "lldb/Breakpoint/StoppointCallbackContext.h" 280b57cec5SDimitry Andric #include "lldb/Breakpoint/WatchpointOptions.h" 290b57cec5SDimitry Andric #include "lldb/Core/Debugger.h" 300b57cec5SDimitry Andric #include "lldb/Core/PluginManager.h" 31bdd1243dSDimitry Andric #include "lldb/Core/ThreadedCommunication.h" 320b57cec5SDimitry Andric #include "lldb/Core/ValueObject.h" 330b57cec5SDimitry Andric #include "lldb/DataFormatters/TypeSummary.h" 340b57cec5SDimitry Andric #include "lldb/Host/FileSystem.h" 350b57cec5SDimitry Andric #include "lldb/Host/HostInfo.h" 360b57cec5SDimitry Andric #include "lldb/Host/Pipe.h" 370b57cec5SDimitry Andric #include "lldb/Interpreter/CommandInterpreter.h" 380b57cec5SDimitry Andric #include "lldb/Interpreter/CommandReturnObject.h" 390b57cec5SDimitry Andric #include "lldb/Target/Thread.h" 400b57cec5SDimitry Andric #include "lldb/Target/ThreadPlan.h" 4104eeddc0SDimitry Andric #include "lldb/Utility/Instrumentation.h" 4281ad6265SDimitry Andric #include "lldb/Utility/LLDBLog.h" 430b57cec5SDimitry Andric #include "lldb/Utility/Timer.h" 440b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h" 450b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h" 465ffd83dbSDimitry Andric #include "llvm/Support/Error.h" 470b57cec5SDimitry Andric #include "llvm/Support/FileSystem.h" 489dba64beSDimitry Andric #include "llvm/Support/FormatAdapters.h" 490b57cec5SDimitry Andric 50fe6060f1SDimitry Andric #include <cstdio> 51fe6060f1SDimitry Andric #include <cstdlib> 520b57cec5SDimitry Andric #include <memory> 530b57cec5SDimitry Andric #include <mutex> 54bdd1243dSDimitry Andric #include <optional> 550b57cec5SDimitry Andric #include <string> 560b57cec5SDimitry Andric 570b57cec5SDimitry Andric using namespace lldb; 580b57cec5SDimitry Andric using namespace lldb_private; 599dba64beSDimitry Andric using namespace lldb_private::python; 609dba64beSDimitry Andric using llvm::Expected; 610b57cec5SDimitry Andric 625ffd83dbSDimitry Andric LLDB_PLUGIN_DEFINE(ScriptInterpreterPython) 635ffd83dbSDimitry Andric 640b57cec5SDimitry Andric // Defined in the SWIG source file 650b57cec5SDimitry Andric extern "C" PyObject *PyInit__lldb(void); 660b57cec5SDimitry Andric 670b57cec5SDimitry Andric #define LLDBSwigPyInit PyInit__lldb 680b57cec5SDimitry Andric 6904eeddc0SDimitry Andric #if defined(_WIN32) 7004eeddc0SDimitry Andric // Don't mess with the signal handlers on Windows. 7104eeddc0SDimitry Andric #define LLDB_USE_PYTHON_SET_INTERRUPT 0 7204eeddc0SDimitry Andric #else 7304eeddc0SDimitry Andric // PyErr_SetInterrupt was introduced in 3.2. 7404eeddc0SDimitry Andric #define LLDB_USE_PYTHON_SET_INTERRUPT \ 7504eeddc0SDimitry Andric (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 2) || (PY_MAJOR_VERSION > 3) 7604eeddc0SDimitry Andric #endif 770b57cec5SDimitry Andric 78e8d8bef9SDimitry Andric static ScriptInterpreterPythonImpl *GetPythonInterpreter(Debugger &debugger) { 79e8d8bef9SDimitry Andric ScriptInterpreter *script_interpreter = 80e8d8bef9SDimitry Andric debugger.GetScriptInterpreter(true, lldb::eScriptLanguagePython); 81e8d8bef9SDimitry Andric return static_cast<ScriptInterpreterPythonImpl *>(script_interpreter); 82e8d8bef9SDimitry Andric } 83e8d8bef9SDimitry Andric 840b57cec5SDimitry Andric namespace { 850b57cec5SDimitry Andric 860b57cec5SDimitry Andric // Initializing Python is not a straightforward process. We cannot control 870b57cec5SDimitry Andric // what external code may have done before getting to this point in LLDB, 880b57cec5SDimitry Andric // including potentially having already initialized Python, so we need to do a 890b57cec5SDimitry Andric // lot of work to ensure that the existing state of the system is maintained 900b57cec5SDimitry Andric // across our initialization. We do this by using an RAII pattern where we 910b57cec5SDimitry Andric // save off initial state at the beginning, and restore it at the end 920b57cec5SDimitry Andric struct InitializePythonRAII { 930b57cec5SDimitry Andric public: 94fe6060f1SDimitry Andric InitializePythonRAII() { 950b57cec5SDimitry Andric InitializePythonHome(); 960b57cec5SDimitry Andric 97c14a5a88SDimitry Andric #ifdef LLDB_USE_LIBEDIT_READLINE_COMPAT_MODULE 98c14a5a88SDimitry Andric // Python's readline is incompatible with libedit being linked into lldb. 99c14a5a88SDimitry Andric // Provide a patched version local to the embedded interpreter. 100c14a5a88SDimitry Andric bool ReadlinePatched = false; 101bdd1243dSDimitry Andric for (auto *p = PyImport_Inittab; p->name != nullptr; p++) { 102c14a5a88SDimitry Andric if (strcmp(p->name, "readline") == 0) { 103c14a5a88SDimitry Andric p->initfunc = initlldb_readline; 104c14a5a88SDimitry Andric break; 105c14a5a88SDimitry Andric } 106c14a5a88SDimitry Andric } 107c14a5a88SDimitry Andric if (!ReadlinePatched) { 108c14a5a88SDimitry Andric PyImport_AppendInittab("readline", initlldb_readline); 109c14a5a88SDimitry Andric ReadlinePatched = true; 110c14a5a88SDimitry Andric } 111c14a5a88SDimitry Andric #endif 112c14a5a88SDimitry Andric 1130b57cec5SDimitry Andric // Register _lldb as a built-in module. 1140b57cec5SDimitry Andric PyImport_AppendInittab("_lldb", LLDBSwigPyInit); 1150b57cec5SDimitry Andric 1160b57cec5SDimitry Andric // Python < 3.2 and Python >= 3.2 reversed the ordering requirements for 1170b57cec5SDimitry Andric // calling `Py_Initialize` and `PyEval_InitThreads`. < 3.2 requires that you 1180b57cec5SDimitry Andric // call `PyEval_InitThreads` first, and >= 3.2 requires that you call it last. 1190b57cec5SDimitry Andric #if (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 2) || (PY_MAJOR_VERSION > 3) 1200b57cec5SDimitry Andric Py_InitializeEx(0); 1210b57cec5SDimitry Andric InitializeThreadsPrivate(); 1220b57cec5SDimitry Andric #else 1230b57cec5SDimitry Andric InitializeThreadsPrivate(); 1240b57cec5SDimitry Andric Py_InitializeEx(0); 1250b57cec5SDimitry Andric #endif 1260b57cec5SDimitry Andric } 1270b57cec5SDimitry Andric 1280b57cec5SDimitry Andric ~InitializePythonRAII() { 1290b57cec5SDimitry Andric if (m_was_already_initialized) { 13081ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Script); 1310b57cec5SDimitry Andric LLDB_LOGV(log, "Releasing PyGILState. Returning to state = {0}locked", 1320b57cec5SDimitry Andric m_gil_state == PyGILState_UNLOCKED ? "un" : ""); 1330b57cec5SDimitry Andric PyGILState_Release(m_gil_state); 1340b57cec5SDimitry Andric } else { 1350b57cec5SDimitry Andric // We initialized the threads in this function, just unlock the GIL. 1360b57cec5SDimitry Andric PyEval_SaveThread(); 1370b57cec5SDimitry Andric } 1380b57cec5SDimitry Andric } 1390b57cec5SDimitry Andric 1400b57cec5SDimitry Andric private: 1410b57cec5SDimitry Andric void InitializePythonHome() { 1425ffd83dbSDimitry Andric #if LLDB_EMBED_PYTHON_HOME 1435ffd83dbSDimitry Andric typedef wchar_t *str_type; 1445ffd83dbSDimitry Andric static str_type g_python_home = []() -> str_type { 1455ffd83dbSDimitry Andric const char *lldb_python_home = LLDB_PYTHON_HOME; 1465ffd83dbSDimitry Andric const char *absolute_python_home = nullptr; 1475ffd83dbSDimitry Andric llvm::SmallString<64> path; 1485ffd83dbSDimitry Andric if (llvm::sys::path::is_absolute(lldb_python_home)) { 1495ffd83dbSDimitry Andric absolute_python_home = lldb_python_home; 1505ffd83dbSDimitry Andric } else { 1515ffd83dbSDimitry Andric FileSpec spec = HostInfo::GetShlibDir(); 1525ffd83dbSDimitry Andric if (!spec) 1535ffd83dbSDimitry Andric return nullptr; 1545ffd83dbSDimitry Andric spec.GetPath(path); 1555ffd83dbSDimitry Andric llvm::sys::path::append(path, lldb_python_home); 1565ffd83dbSDimitry Andric absolute_python_home = path.c_str(); 1575ffd83dbSDimitry Andric } 1580b57cec5SDimitry Andric size_t size = 0; 1595ffd83dbSDimitry Andric return Py_DecodeLocale(absolute_python_home, &size); 1605ffd83dbSDimitry Andric }(); 1615ffd83dbSDimitry Andric if (g_python_home != nullptr) { 1620b57cec5SDimitry Andric Py_SetPythonHome(g_python_home); 1635ffd83dbSDimitry Andric } 1640b57cec5SDimitry Andric #endif 1650b57cec5SDimitry Andric } 1660b57cec5SDimitry Andric 1670b57cec5SDimitry Andric void InitializeThreadsPrivate() { 1680b57cec5SDimitry Andric // Since Python 3.7 `Py_Initialize` calls `PyEval_InitThreads` inside itself, 1690b57cec5SDimitry Andric // so there is no way to determine whether the embedded interpreter 1700b57cec5SDimitry Andric // was already initialized by some external code. `PyEval_ThreadsInitialized` 1710b57cec5SDimitry Andric // would always return `true` and `PyGILState_Ensure/Release` flow would be 1720b57cec5SDimitry Andric // executed instead of unlocking GIL with `PyEval_SaveThread`. When 1730b57cec5SDimitry Andric // an another thread calls `PyGILState_Ensure` it would get stuck in deadlock. 1740b57cec5SDimitry Andric #if (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 7) || (PY_MAJOR_VERSION > 3) 1750b57cec5SDimitry Andric // The only case we should go further and acquire the GIL: it is unlocked. 1760b57cec5SDimitry Andric if (PyGILState_Check()) 1770b57cec5SDimitry Andric return; 1780b57cec5SDimitry Andric #endif 1790b57cec5SDimitry Andric 1800b57cec5SDimitry Andric if (PyEval_ThreadsInitialized()) { 18181ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Script); 1820b57cec5SDimitry Andric 1830b57cec5SDimitry Andric m_was_already_initialized = true; 1840b57cec5SDimitry Andric m_gil_state = PyGILState_Ensure(); 1850b57cec5SDimitry Andric LLDB_LOGV(log, "Ensured PyGILState. Previous state = {0}locked\n", 1860b57cec5SDimitry Andric m_gil_state == PyGILState_UNLOCKED ? "un" : ""); 1870b57cec5SDimitry Andric return; 1880b57cec5SDimitry Andric } 1890b57cec5SDimitry Andric 1900b57cec5SDimitry Andric // InitThreads acquires the GIL if it hasn't been called before. 1910b57cec5SDimitry Andric PyEval_InitThreads(); 1920b57cec5SDimitry Andric } 1930b57cec5SDimitry Andric 194fe6060f1SDimitry Andric PyGILState_STATE m_gil_state = PyGILState_UNLOCKED; 195fe6060f1SDimitry Andric bool m_was_already_initialized = false; 1960b57cec5SDimitry Andric }; 19704eeddc0SDimitry Andric 19804eeddc0SDimitry Andric #if LLDB_USE_PYTHON_SET_INTERRUPT 19904eeddc0SDimitry Andric /// Saves the current signal handler for the specified signal and restores 20004eeddc0SDimitry Andric /// it at the end of the current scope. 20104eeddc0SDimitry Andric struct RestoreSignalHandlerScope { 20204eeddc0SDimitry Andric /// The signal handler. 20304eeddc0SDimitry Andric struct sigaction m_prev_handler; 20404eeddc0SDimitry Andric int m_signal_code; 20504eeddc0SDimitry Andric RestoreSignalHandlerScope(int signal_code) : m_signal_code(signal_code) { 20604eeddc0SDimitry Andric // Initialize sigaction to their default state. 20704eeddc0SDimitry Andric std::memset(&m_prev_handler, 0, sizeof(m_prev_handler)); 20804eeddc0SDimitry Andric // Don't install a new handler, just read back the old one. 20904eeddc0SDimitry Andric struct sigaction *new_handler = nullptr; 21004eeddc0SDimitry Andric int signal_err = ::sigaction(m_signal_code, new_handler, &m_prev_handler); 21104eeddc0SDimitry Andric lldbassert(signal_err == 0 && "sigaction failed to read handler"); 21204eeddc0SDimitry Andric } 21304eeddc0SDimitry Andric ~RestoreSignalHandlerScope() { 21404eeddc0SDimitry Andric int signal_err = ::sigaction(m_signal_code, &m_prev_handler, nullptr); 21504eeddc0SDimitry Andric lldbassert(signal_err == 0 && "sigaction failed to restore old handler"); 21604eeddc0SDimitry Andric } 21704eeddc0SDimitry Andric }; 21804eeddc0SDimitry Andric #endif 2190b57cec5SDimitry Andric } // namespace 2200b57cec5SDimitry Andric 2210b57cec5SDimitry Andric void ScriptInterpreterPython::ComputePythonDirForApple( 2220b57cec5SDimitry Andric llvm::SmallVectorImpl<char> &path) { 2230b57cec5SDimitry Andric auto style = llvm::sys::path::Style::posix; 2240b57cec5SDimitry Andric 2250b57cec5SDimitry Andric llvm::StringRef path_ref(path.begin(), path.size()); 2260b57cec5SDimitry Andric auto rbegin = llvm::sys::path::rbegin(path_ref, style); 2270b57cec5SDimitry Andric auto rend = llvm::sys::path::rend(path_ref); 2280b57cec5SDimitry Andric auto framework = std::find(rbegin, rend, "LLDB.framework"); 2290b57cec5SDimitry Andric if (framework == rend) { 2309dba64beSDimitry Andric ComputePythonDir(path); 2310b57cec5SDimitry Andric return; 2320b57cec5SDimitry Andric } 2330b57cec5SDimitry Andric path.resize(framework - rend); 2340b57cec5SDimitry Andric llvm::sys::path::append(path, style, "LLDB.framework", "Resources", "Python"); 2350b57cec5SDimitry Andric } 2360b57cec5SDimitry Andric 2379dba64beSDimitry Andric void ScriptInterpreterPython::ComputePythonDir( 2380b57cec5SDimitry Andric llvm::SmallVectorImpl<char> &path) { 2390b57cec5SDimitry Andric // Build the path by backing out of the lib dir, then building with whatever 2400b57cec5SDimitry Andric // the real python interpreter uses. (e.g. lib for most, lib64 on RHEL 2419dba64beSDimitry Andric // x86_64, or bin on Windows). 2429dba64beSDimitry Andric llvm::sys::path::remove_filename(path); 2439dba64beSDimitry Andric llvm::sys::path::append(path, LLDB_PYTHON_RELATIVE_LIBDIR); 2440b57cec5SDimitry Andric 2459dba64beSDimitry Andric #if defined(_WIN32) 246bdd1243dSDimitry Andric // This will be injected directly through FileSpec.SetDirectory(), 2470b57cec5SDimitry Andric // so we need to normalize manually. 2480b57cec5SDimitry Andric std::replace(path.begin(), path.end(), '\\', '/'); 2499dba64beSDimitry Andric #endif 2500b57cec5SDimitry Andric } 2510b57cec5SDimitry Andric 2520b57cec5SDimitry Andric FileSpec ScriptInterpreterPython::GetPythonDir() { 2530b57cec5SDimitry Andric static FileSpec g_spec = []() { 2540b57cec5SDimitry Andric FileSpec spec = HostInfo::GetShlibDir(); 2550b57cec5SDimitry Andric if (!spec) 2560b57cec5SDimitry Andric return FileSpec(); 2570b57cec5SDimitry Andric llvm::SmallString<64> path; 2580b57cec5SDimitry Andric spec.GetPath(path); 2590b57cec5SDimitry Andric 2600b57cec5SDimitry Andric #if defined(__APPLE__) 2610b57cec5SDimitry Andric ComputePythonDirForApple(path); 2620b57cec5SDimitry Andric #else 2639dba64beSDimitry Andric ComputePythonDir(path); 2640b57cec5SDimitry Andric #endif 265bdd1243dSDimitry Andric spec.SetDirectory(path); 2660b57cec5SDimitry Andric return spec; 2670b57cec5SDimitry Andric }(); 2680b57cec5SDimitry Andric return g_spec; 2690b57cec5SDimitry Andric } 2700b57cec5SDimitry Andric 271349cc55cSDimitry Andric static const char GetInterpreterInfoScript[] = R"( 272349cc55cSDimitry Andric import os 273349cc55cSDimitry Andric import sys 274349cc55cSDimitry Andric 275349cc55cSDimitry Andric def main(lldb_python_dir, python_exe_relative_path): 276349cc55cSDimitry Andric info = { 277349cc55cSDimitry Andric "lldb-pythonpath": lldb_python_dir, 278349cc55cSDimitry Andric "language": "python", 279349cc55cSDimitry Andric "prefix": sys.prefix, 280349cc55cSDimitry Andric "executable": os.path.join(sys.prefix, python_exe_relative_path) 281349cc55cSDimitry Andric } 282349cc55cSDimitry Andric return info 283349cc55cSDimitry Andric )"; 284349cc55cSDimitry Andric 285349cc55cSDimitry Andric static const char python_exe_relative_path[] = LLDB_PYTHON_EXE_RELATIVE_PATH; 286349cc55cSDimitry Andric 287349cc55cSDimitry Andric StructuredData::DictionarySP ScriptInterpreterPython::GetInterpreterInfo() { 288349cc55cSDimitry Andric GIL gil; 289349cc55cSDimitry Andric FileSpec python_dir_spec = GetPythonDir(); 290349cc55cSDimitry Andric if (!python_dir_spec) 291349cc55cSDimitry Andric return nullptr; 292349cc55cSDimitry Andric PythonScript get_info(GetInterpreterInfoScript); 293349cc55cSDimitry Andric auto info_json = unwrapIgnoringErrors( 294349cc55cSDimitry Andric As<PythonDictionary>(get_info(PythonString(python_dir_spec.GetPath()), 295349cc55cSDimitry Andric PythonString(python_exe_relative_path)))); 296349cc55cSDimitry Andric if (!info_json) 297349cc55cSDimitry Andric return nullptr; 298349cc55cSDimitry Andric return info_json.CreateStructuredDictionary(); 299349cc55cSDimitry Andric } 300349cc55cSDimitry Andric 301fe6060f1SDimitry Andric void ScriptInterpreterPython::SharedLibraryDirectoryHelper( 302fe6060f1SDimitry Andric FileSpec &this_file) { 303fe6060f1SDimitry Andric // When we're loaded from python, this_file will point to the file inside the 304fe6060f1SDimitry Andric // python package directory. Replace it with the one in the lib directory. 305fe6060f1SDimitry Andric #ifdef _WIN32 306fe6060f1SDimitry Andric // On windows, we need to manually back out of the python tree, and go into 307fe6060f1SDimitry Andric // the bin directory. This is pretty much the inverse of what ComputePythonDir 308fe6060f1SDimitry Andric // does. 309*fe013be4SDimitry Andric if (this_file.GetFileNameExtension() == ".pyd") { 310fe6060f1SDimitry Andric this_file.RemoveLastPathComponent(); // _lldb.pyd or _lldb_d.pyd 311fe6060f1SDimitry Andric this_file.RemoveLastPathComponent(); // lldb 312fe6060f1SDimitry Andric llvm::StringRef libdir = LLDB_PYTHON_RELATIVE_LIBDIR; 313fe6060f1SDimitry Andric for (auto it = llvm::sys::path::begin(libdir), 314fe6060f1SDimitry Andric end = llvm::sys::path::end(libdir); 315fe6060f1SDimitry Andric it != end; ++it) 316fe6060f1SDimitry Andric this_file.RemoveLastPathComponent(); 317fe6060f1SDimitry Andric this_file.AppendPathComponent("bin"); 318fe6060f1SDimitry Andric this_file.AppendPathComponent("liblldb.dll"); 319fe6060f1SDimitry Andric } 320fe6060f1SDimitry Andric #else 321fe6060f1SDimitry Andric // The python file is a symlink, so we can find the real library by resolving 322fe6060f1SDimitry Andric // it. We can do this unconditionally. 323fe6060f1SDimitry Andric FileSystem::Instance().ResolveSymbolicLink(this_file, this_file); 324fe6060f1SDimitry Andric #endif 325fe6060f1SDimitry Andric } 326fe6060f1SDimitry Andric 327349cc55cSDimitry Andric llvm::StringRef ScriptInterpreterPython::GetPluginDescriptionStatic() { 3280b57cec5SDimitry Andric return "Embedded Python interpreter"; 3290b57cec5SDimitry Andric } 3300b57cec5SDimitry Andric 3310b57cec5SDimitry Andric void ScriptInterpreterPython::Initialize() { 3320b57cec5SDimitry Andric static llvm::once_flag g_once_flag; 3330b57cec5SDimitry Andric llvm::call_once(g_once_flag, []() { 3340b57cec5SDimitry Andric PluginManager::RegisterPlugin(GetPluginNameStatic(), 3350b57cec5SDimitry Andric GetPluginDescriptionStatic(), 3360b57cec5SDimitry Andric lldb::eScriptLanguagePython, 3370b57cec5SDimitry Andric ScriptInterpreterPythonImpl::CreateInstance); 33804eeddc0SDimitry Andric ScriptInterpreterPythonImpl::Initialize(); 3390b57cec5SDimitry Andric }); 3400b57cec5SDimitry Andric } 3410b57cec5SDimitry Andric 3420b57cec5SDimitry Andric void ScriptInterpreterPython::Terminate() {} 3430b57cec5SDimitry Andric 3440b57cec5SDimitry Andric ScriptInterpreterPythonImpl::Locker::Locker( 3450b57cec5SDimitry Andric ScriptInterpreterPythonImpl *py_interpreter, uint16_t on_entry, 3469dba64beSDimitry Andric uint16_t on_leave, FileSP in, FileSP out, FileSP err) 3470b57cec5SDimitry Andric : ScriptInterpreterLocker(), 3480b57cec5SDimitry Andric m_teardown_session((on_leave & TearDownSession) == TearDownSession), 3490b57cec5SDimitry Andric m_python_interpreter(py_interpreter) { 3500b57cec5SDimitry Andric DoAcquireLock(); 3510b57cec5SDimitry Andric if ((on_entry & InitSession) == InitSession) { 3520b57cec5SDimitry Andric if (!DoInitSession(on_entry, in, out, err)) { 3530b57cec5SDimitry Andric // Don't teardown the session if we didn't init it. 3540b57cec5SDimitry Andric m_teardown_session = false; 3550b57cec5SDimitry Andric } 3560b57cec5SDimitry Andric } 3570b57cec5SDimitry Andric } 3580b57cec5SDimitry Andric 3590b57cec5SDimitry Andric bool ScriptInterpreterPythonImpl::Locker::DoAcquireLock() { 36081ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Script); 3610b57cec5SDimitry Andric m_GILState = PyGILState_Ensure(); 3620b57cec5SDimitry Andric LLDB_LOGV(log, "Ensured PyGILState. Previous state = {0}locked", 3630b57cec5SDimitry Andric m_GILState == PyGILState_UNLOCKED ? "un" : ""); 3640b57cec5SDimitry Andric 3650b57cec5SDimitry Andric // we need to save the thread state when we first start the command because 3660b57cec5SDimitry Andric // we might decide to interrupt it while some action is taking place outside 3670b57cec5SDimitry Andric // of Python (e.g. printing to screen, waiting for the network, ...) in that 3680b57cec5SDimitry Andric // case, _PyThreadState_Current will be NULL - and we would be unable to set 3690b57cec5SDimitry Andric // the asynchronous exception - not a desirable situation 3700b57cec5SDimitry Andric m_python_interpreter->SetThreadState(PyThreadState_Get()); 3710b57cec5SDimitry Andric m_python_interpreter->IncrementLockCount(); 3720b57cec5SDimitry Andric return true; 3730b57cec5SDimitry Andric } 3740b57cec5SDimitry Andric 3750b57cec5SDimitry Andric bool ScriptInterpreterPythonImpl::Locker::DoInitSession(uint16_t on_entry_flags, 3769dba64beSDimitry Andric FileSP in, FileSP out, 3779dba64beSDimitry Andric FileSP err) { 3780b57cec5SDimitry Andric if (!m_python_interpreter) 3790b57cec5SDimitry Andric return false; 3800b57cec5SDimitry Andric return m_python_interpreter->EnterSession(on_entry_flags, in, out, err); 3810b57cec5SDimitry Andric } 3820b57cec5SDimitry Andric 3830b57cec5SDimitry Andric bool ScriptInterpreterPythonImpl::Locker::DoFreeLock() { 38481ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Script); 3850b57cec5SDimitry Andric LLDB_LOGV(log, "Releasing PyGILState. Returning to state = {0}locked", 3860b57cec5SDimitry Andric m_GILState == PyGILState_UNLOCKED ? "un" : ""); 3870b57cec5SDimitry Andric PyGILState_Release(m_GILState); 3880b57cec5SDimitry Andric m_python_interpreter->DecrementLockCount(); 3890b57cec5SDimitry Andric return true; 3900b57cec5SDimitry Andric } 3910b57cec5SDimitry Andric 3920b57cec5SDimitry Andric bool ScriptInterpreterPythonImpl::Locker::DoTearDownSession() { 3930b57cec5SDimitry Andric if (!m_python_interpreter) 3940b57cec5SDimitry Andric return false; 3950b57cec5SDimitry Andric m_python_interpreter->LeaveSession(); 3960b57cec5SDimitry Andric return true; 3970b57cec5SDimitry Andric } 3980b57cec5SDimitry Andric 3990b57cec5SDimitry Andric ScriptInterpreterPythonImpl::Locker::~Locker() { 4000b57cec5SDimitry Andric if (m_teardown_session) 4010b57cec5SDimitry Andric DoTearDownSession(); 4020b57cec5SDimitry Andric DoFreeLock(); 4030b57cec5SDimitry Andric } 4040b57cec5SDimitry Andric 4050b57cec5SDimitry Andric ScriptInterpreterPythonImpl::ScriptInterpreterPythonImpl(Debugger &debugger) 4060b57cec5SDimitry Andric : ScriptInterpreterPython(debugger), m_saved_stdin(), m_saved_stdout(), 4070b57cec5SDimitry Andric m_saved_stderr(), m_main_module(), 4080b57cec5SDimitry Andric m_session_dict(PyInitialValue::Invalid), 4090b57cec5SDimitry Andric m_sys_module_dict(PyInitialValue::Invalid), m_run_one_line_function(), 4100b57cec5SDimitry Andric m_run_one_line_str_global(), 411*fe013be4SDimitry Andric m_dictionary_name(m_debugger.GetInstanceName()), 4129dba64beSDimitry Andric m_active_io_handler(eIOHandlerNone), m_session_is_active(false), 4135ffd83dbSDimitry Andric m_pty_secondary_is_open(false), m_valid_session(true), m_lock_count(0), 4149dba64beSDimitry Andric m_command_thread_state(nullptr) { 415bdd1243dSDimitry Andric m_scripted_platform_interface_up = 416bdd1243dSDimitry Andric std::make_unique<ScriptedPlatformPythonInterface>(*this); 417fe6060f1SDimitry Andric 4180b57cec5SDimitry Andric m_dictionary_name.append("_dict"); 4190b57cec5SDimitry Andric StreamString run_string; 4200b57cec5SDimitry Andric run_string.Printf("%s = dict()", m_dictionary_name.c_str()); 4210b57cec5SDimitry Andric 4220b57cec5SDimitry Andric Locker locker(this, Locker::AcquireLock, Locker::FreeAcquiredLock); 4230b57cec5SDimitry Andric PyRun_SimpleString(run_string.GetData()); 4240b57cec5SDimitry Andric 4250b57cec5SDimitry Andric run_string.Clear(); 4260b57cec5SDimitry Andric run_string.Printf( 4270b57cec5SDimitry Andric "run_one_line (%s, 'import copy, keyword, os, re, sys, uuid, lldb')", 4280b57cec5SDimitry Andric m_dictionary_name.c_str()); 4290b57cec5SDimitry Andric PyRun_SimpleString(run_string.GetData()); 4300b57cec5SDimitry Andric 4310b57cec5SDimitry Andric // Reloading modules requires a different syntax in Python 2 and Python 3. 4320b57cec5SDimitry Andric // This provides a consistent syntax no matter what version of Python. 4330b57cec5SDimitry Andric run_string.Clear(); 434bdd1243dSDimitry Andric run_string.Printf("run_one_line (%s, 'from importlib import reload as reload_module')", 4350b57cec5SDimitry Andric m_dictionary_name.c_str()); 4360b57cec5SDimitry Andric PyRun_SimpleString(run_string.GetData()); 4370b57cec5SDimitry Andric 4380b57cec5SDimitry Andric // WARNING: temporary code that loads Cocoa formatters - this should be done 4390b57cec5SDimitry Andric // on a per-platform basis rather than loading the whole set and letting the 4400b57cec5SDimitry Andric // individual formatter classes exploit APIs to check whether they can/cannot 4410b57cec5SDimitry Andric // do their task 4420b57cec5SDimitry Andric run_string.Clear(); 4430b57cec5SDimitry Andric run_string.Printf( 444*fe013be4SDimitry Andric "run_one_line (%s, 'import lldb.formatters, lldb.formatters.cpp')", 4450b57cec5SDimitry Andric m_dictionary_name.c_str()); 4460b57cec5SDimitry Andric PyRun_SimpleString(run_string.GetData()); 4470b57cec5SDimitry Andric run_string.Clear(); 4480b57cec5SDimitry Andric 4490b57cec5SDimitry Andric run_string.Printf("run_one_line (%s, 'import lldb.embedded_interpreter; from " 4500b57cec5SDimitry Andric "lldb.embedded_interpreter import run_python_interpreter; " 4510b57cec5SDimitry Andric "from lldb.embedded_interpreter import run_one_line')", 4520b57cec5SDimitry Andric m_dictionary_name.c_str()); 4530b57cec5SDimitry Andric PyRun_SimpleString(run_string.GetData()); 4540b57cec5SDimitry Andric run_string.Clear(); 4550b57cec5SDimitry Andric 4560b57cec5SDimitry Andric run_string.Printf("run_one_line (%s, 'lldb.debugger_unique_id = %" PRIu64 457*fe013be4SDimitry Andric "')", 4580b57cec5SDimitry Andric m_dictionary_name.c_str(), m_debugger.GetID()); 4590b57cec5SDimitry Andric PyRun_SimpleString(run_string.GetData()); 4600b57cec5SDimitry Andric } 4610b57cec5SDimitry Andric 4620b57cec5SDimitry Andric ScriptInterpreterPythonImpl::~ScriptInterpreterPythonImpl() { 4630b57cec5SDimitry Andric // the session dictionary may hold objects with complex state which means 4640b57cec5SDimitry Andric // that they may need to be torn down with some level of smarts and that, in 4650b57cec5SDimitry Andric // turn, requires a valid thread state force Python to procure itself such a 4660b57cec5SDimitry Andric // thread state, nuke the session dictionary and then release it for others 4670b57cec5SDimitry Andric // to use and proceed with the rest of the shutdown 4680b57cec5SDimitry Andric auto gil_state = PyGILState_Ensure(); 4690b57cec5SDimitry Andric m_session_dict.Reset(); 4700b57cec5SDimitry Andric PyGILState_Release(gil_state); 4710b57cec5SDimitry Andric } 4720b57cec5SDimitry Andric 4730b57cec5SDimitry Andric void ScriptInterpreterPythonImpl::IOHandlerActivated(IOHandler &io_handler, 4740b57cec5SDimitry Andric bool interactive) { 4750b57cec5SDimitry Andric const char *instructions = nullptr; 4760b57cec5SDimitry Andric 4770b57cec5SDimitry Andric switch (m_active_io_handler) { 4780b57cec5SDimitry Andric case eIOHandlerNone: 4790b57cec5SDimitry Andric break; 4800b57cec5SDimitry Andric case eIOHandlerBreakpoint: 4810b57cec5SDimitry Andric instructions = R"(Enter your Python command(s). Type 'DONE' to end. 4820b57cec5SDimitry Andric def function (frame, bp_loc, internal_dict): 4830b57cec5SDimitry Andric """frame: the lldb.SBFrame for the location at which you stopped 4840b57cec5SDimitry Andric bp_loc: an lldb.SBBreakpointLocation for the breakpoint location information 4850b57cec5SDimitry Andric internal_dict: an LLDB support object not to be used""" 4860b57cec5SDimitry Andric )"; 4870b57cec5SDimitry Andric break; 4880b57cec5SDimitry Andric case eIOHandlerWatchpoint: 4890b57cec5SDimitry Andric instructions = "Enter your Python command(s). Type 'DONE' to end.\n"; 4900b57cec5SDimitry Andric break; 4910b57cec5SDimitry Andric } 4920b57cec5SDimitry Andric 4930b57cec5SDimitry Andric if (instructions) { 4949dba64beSDimitry Andric StreamFileSP output_sp(io_handler.GetOutputStreamFileSP()); 4950b57cec5SDimitry Andric if (output_sp && interactive) { 4960b57cec5SDimitry Andric output_sp->PutCString(instructions); 4970b57cec5SDimitry Andric output_sp->Flush(); 4980b57cec5SDimitry Andric } 4990b57cec5SDimitry Andric } 5000b57cec5SDimitry Andric } 5010b57cec5SDimitry Andric 5020b57cec5SDimitry Andric void ScriptInterpreterPythonImpl::IOHandlerInputComplete(IOHandler &io_handler, 5030b57cec5SDimitry Andric std::string &data) { 5040b57cec5SDimitry Andric io_handler.SetIsDone(true); 5050b57cec5SDimitry Andric bool batch_mode = m_debugger.GetCommandInterpreter().GetBatchCommandMode(); 5060b57cec5SDimitry Andric 5070b57cec5SDimitry Andric switch (m_active_io_handler) { 5080b57cec5SDimitry Andric case eIOHandlerNone: 5090b57cec5SDimitry Andric break; 5100b57cec5SDimitry Andric case eIOHandlerBreakpoint: { 511fe6060f1SDimitry Andric std::vector<std::reference_wrapper<BreakpointOptions>> *bp_options_vec = 512fe6060f1SDimitry Andric (std::vector<std::reference_wrapper<BreakpointOptions>> *) 513fe6060f1SDimitry Andric io_handler.GetUserData(); 514fe6060f1SDimitry Andric for (BreakpointOptions &bp_options : *bp_options_vec) { 5150b57cec5SDimitry Andric 5169dba64beSDimitry Andric auto data_up = std::make_unique<CommandDataPython>(); 5170b57cec5SDimitry Andric if (!data_up) 5180b57cec5SDimitry Andric break; 5190b57cec5SDimitry Andric data_up->user_source.SplitIntoLines(data); 5200b57cec5SDimitry Andric 521480093f4SDimitry Andric StructuredData::ObjectSP empty_args_sp; 5220b57cec5SDimitry Andric if (GenerateBreakpointCommandCallbackData(data_up->user_source, 523480093f4SDimitry Andric data_up->script_source, 524*fe013be4SDimitry Andric /*has_extra_args=*/false, 525*fe013be4SDimitry Andric /*is_callback=*/false) 5260b57cec5SDimitry Andric .Success()) { 5270b57cec5SDimitry Andric auto baton_sp = std::make_shared<BreakpointOptions::CommandBaton>( 5280b57cec5SDimitry Andric std::move(data_up)); 529fe6060f1SDimitry Andric bp_options.SetCallback( 5300b57cec5SDimitry Andric ScriptInterpreterPythonImpl::BreakpointCallbackFunction, baton_sp); 5310b57cec5SDimitry Andric } else if (!batch_mode) { 5329dba64beSDimitry Andric StreamFileSP error_sp = io_handler.GetErrorStreamFileSP(); 5330b57cec5SDimitry Andric if (error_sp) { 5340b57cec5SDimitry Andric error_sp->Printf("Warning: No command attached to breakpoint.\n"); 5350b57cec5SDimitry Andric error_sp->Flush(); 5360b57cec5SDimitry Andric } 5370b57cec5SDimitry Andric } 5380b57cec5SDimitry Andric } 5390b57cec5SDimitry Andric m_active_io_handler = eIOHandlerNone; 5400b57cec5SDimitry Andric } break; 5410b57cec5SDimitry Andric case eIOHandlerWatchpoint: { 5420b57cec5SDimitry Andric WatchpointOptions *wp_options = 5430b57cec5SDimitry Andric (WatchpointOptions *)io_handler.GetUserData(); 5449dba64beSDimitry Andric auto data_up = std::make_unique<WatchpointOptions::CommandData>(); 5450b57cec5SDimitry Andric data_up->user_source.SplitIntoLines(data); 5460b57cec5SDimitry Andric 5470b57cec5SDimitry Andric if (GenerateWatchpointCommandCallbackData(data_up->user_source, 548*fe013be4SDimitry Andric data_up->script_source, 549*fe013be4SDimitry Andric /*is_callback=*/false)) { 5500b57cec5SDimitry Andric auto baton_sp = 5510b57cec5SDimitry Andric std::make_shared<WatchpointOptions::CommandBaton>(std::move(data_up)); 5520b57cec5SDimitry Andric wp_options->SetCallback( 5530b57cec5SDimitry Andric ScriptInterpreterPythonImpl::WatchpointCallbackFunction, baton_sp); 5540b57cec5SDimitry Andric } else if (!batch_mode) { 5559dba64beSDimitry Andric StreamFileSP error_sp = io_handler.GetErrorStreamFileSP(); 5560b57cec5SDimitry Andric if (error_sp) { 5570b57cec5SDimitry Andric error_sp->Printf("Warning: No command attached to breakpoint.\n"); 5580b57cec5SDimitry Andric error_sp->Flush(); 5590b57cec5SDimitry Andric } 5600b57cec5SDimitry Andric } 5610b57cec5SDimitry Andric m_active_io_handler = eIOHandlerNone; 5620b57cec5SDimitry Andric } break; 5630b57cec5SDimitry Andric } 5640b57cec5SDimitry Andric } 5650b57cec5SDimitry Andric 5660b57cec5SDimitry Andric lldb::ScriptInterpreterSP 5670b57cec5SDimitry Andric ScriptInterpreterPythonImpl::CreateInstance(Debugger &debugger) { 5680b57cec5SDimitry Andric return std::make_shared<ScriptInterpreterPythonImpl>(debugger); 5690b57cec5SDimitry Andric } 5700b57cec5SDimitry Andric 5710b57cec5SDimitry Andric void ScriptInterpreterPythonImpl::LeaveSession() { 57281ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Script); 5730b57cec5SDimitry Andric if (log) 5740b57cec5SDimitry Andric log->PutCString("ScriptInterpreterPythonImpl::LeaveSession()"); 5750b57cec5SDimitry Andric 5769dba64beSDimitry Andric // Unset the LLDB global variables. 5779dba64beSDimitry Andric PyRun_SimpleString("lldb.debugger = None; lldb.target = None; lldb.process " 5789dba64beSDimitry Andric "= None; lldb.thread = None; lldb.frame = None"); 5799dba64beSDimitry Andric 5800b57cec5SDimitry Andric // checking that we have a valid thread state - since we use our own 5810b57cec5SDimitry Andric // threading and locking in some (rare) cases during cleanup Python may end 5820b57cec5SDimitry Andric // up believing we have no thread state and PyImport_AddModule will crash if 5830b57cec5SDimitry Andric // that is the case - since that seems to only happen when destroying the 5840b57cec5SDimitry Andric // SBDebugger, we can make do without clearing up stdout and stderr 5850b57cec5SDimitry Andric 5860b57cec5SDimitry Andric // rdar://problem/11292882 5870b57cec5SDimitry Andric // When the current thread state is NULL, PyThreadState_Get() issues a fatal 5880b57cec5SDimitry Andric // error. 5890b57cec5SDimitry Andric if (PyThreadState_GetDict()) { 5900b57cec5SDimitry Andric PythonDictionary &sys_module_dict = GetSysModuleDictionary(); 5910b57cec5SDimitry Andric if (sys_module_dict.IsValid()) { 5920b57cec5SDimitry Andric if (m_saved_stdin.IsValid()) { 5930b57cec5SDimitry Andric sys_module_dict.SetItemForKey(PythonString("stdin"), m_saved_stdin); 5940b57cec5SDimitry Andric m_saved_stdin.Reset(); 5950b57cec5SDimitry Andric } 5960b57cec5SDimitry Andric if (m_saved_stdout.IsValid()) { 5970b57cec5SDimitry Andric sys_module_dict.SetItemForKey(PythonString("stdout"), m_saved_stdout); 5980b57cec5SDimitry Andric m_saved_stdout.Reset(); 5990b57cec5SDimitry Andric } 6000b57cec5SDimitry Andric if (m_saved_stderr.IsValid()) { 6010b57cec5SDimitry Andric sys_module_dict.SetItemForKey(PythonString("stderr"), m_saved_stderr); 6020b57cec5SDimitry Andric m_saved_stderr.Reset(); 6030b57cec5SDimitry Andric } 6040b57cec5SDimitry Andric } 6050b57cec5SDimitry Andric } 6060b57cec5SDimitry Andric 6070b57cec5SDimitry Andric m_session_is_active = false; 6080b57cec5SDimitry Andric } 6090b57cec5SDimitry Andric 6109dba64beSDimitry Andric bool ScriptInterpreterPythonImpl::SetStdHandle(FileSP file_sp, 6119dba64beSDimitry Andric const char *py_name, 6129dba64beSDimitry Andric PythonObject &save_file, 6130b57cec5SDimitry Andric const char *mode) { 6149dba64beSDimitry Andric if (!file_sp || !*file_sp) { 6159dba64beSDimitry Andric save_file.Reset(); 6169dba64beSDimitry Andric return false; 6179dba64beSDimitry Andric } 6189dba64beSDimitry Andric File &file = *file_sp; 6199dba64beSDimitry Andric 6200b57cec5SDimitry Andric // Flush the file before giving it to python to avoid interleaved output. 6210b57cec5SDimitry Andric file.Flush(); 6220b57cec5SDimitry Andric 6230b57cec5SDimitry Andric PythonDictionary &sys_module_dict = GetSysModuleDictionary(); 6240b57cec5SDimitry Andric 6259dba64beSDimitry Andric auto new_file = PythonFile::FromFile(file, mode); 6269dba64beSDimitry Andric if (!new_file) { 6279dba64beSDimitry Andric llvm::consumeError(new_file.takeError()); 6280b57cec5SDimitry Andric return false; 6290b57cec5SDimitry Andric } 6300b57cec5SDimitry Andric 6319dba64beSDimitry Andric save_file = sys_module_dict.GetItemForKey(PythonString(py_name)); 6329dba64beSDimitry Andric 6339dba64beSDimitry Andric sys_module_dict.SetItemForKey(PythonString(py_name), new_file.get()); 6349dba64beSDimitry Andric return true; 6359dba64beSDimitry Andric } 6369dba64beSDimitry Andric 6370b57cec5SDimitry Andric bool ScriptInterpreterPythonImpl::EnterSession(uint16_t on_entry_flags, 6389dba64beSDimitry Andric FileSP in_sp, FileSP out_sp, 6399dba64beSDimitry Andric FileSP err_sp) { 6400b57cec5SDimitry Andric // If we have already entered the session, without having officially 'left' 6410b57cec5SDimitry Andric // it, then there is no need to 'enter' it again. 64281ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Script); 6430b57cec5SDimitry Andric if (m_session_is_active) { 6449dba64beSDimitry Andric LLDB_LOGF( 6459dba64beSDimitry Andric log, 6460b57cec5SDimitry Andric "ScriptInterpreterPythonImpl::EnterSession(on_entry_flags=0x%" PRIx16 6470b57cec5SDimitry Andric ") session is already active, returning without doing anything", 6480b57cec5SDimitry Andric on_entry_flags); 6490b57cec5SDimitry Andric return false; 6500b57cec5SDimitry Andric } 6510b57cec5SDimitry Andric 6529dba64beSDimitry Andric LLDB_LOGF( 6539dba64beSDimitry Andric log, 6549dba64beSDimitry Andric "ScriptInterpreterPythonImpl::EnterSession(on_entry_flags=0x%" PRIx16 ")", 6550b57cec5SDimitry Andric on_entry_flags); 6560b57cec5SDimitry Andric 6570b57cec5SDimitry Andric m_session_is_active = true; 6580b57cec5SDimitry Andric 6590b57cec5SDimitry Andric StreamString run_string; 6600b57cec5SDimitry Andric 6610b57cec5SDimitry Andric if (on_entry_flags & Locker::InitGlobals) { 6620b57cec5SDimitry Andric run_string.Printf("run_one_line (%s, 'lldb.debugger_unique_id = %" PRIu64, 6630b57cec5SDimitry Andric m_dictionary_name.c_str(), m_debugger.GetID()); 6640b57cec5SDimitry Andric run_string.Printf( 6650b57cec5SDimitry Andric "; lldb.debugger = lldb.SBDebugger.FindDebuggerWithID (%" PRIu64 ")", 6660b57cec5SDimitry Andric m_debugger.GetID()); 6670b57cec5SDimitry Andric run_string.PutCString("; lldb.target = lldb.debugger.GetSelectedTarget()"); 6680b57cec5SDimitry Andric run_string.PutCString("; lldb.process = lldb.target.GetProcess()"); 6690b57cec5SDimitry Andric run_string.PutCString("; lldb.thread = lldb.process.GetSelectedThread ()"); 6700b57cec5SDimitry Andric run_string.PutCString("; lldb.frame = lldb.thread.GetSelectedFrame ()"); 6710b57cec5SDimitry Andric run_string.PutCString("')"); 6720b57cec5SDimitry Andric } else { 6730b57cec5SDimitry Andric // If we aren't initing the globals, we should still always set the 6740b57cec5SDimitry Andric // debugger (since that is always unique.) 6750b57cec5SDimitry Andric run_string.Printf("run_one_line (%s, 'lldb.debugger_unique_id = %" PRIu64, 6760b57cec5SDimitry Andric m_dictionary_name.c_str(), m_debugger.GetID()); 6770b57cec5SDimitry Andric run_string.Printf( 6780b57cec5SDimitry Andric "; lldb.debugger = lldb.SBDebugger.FindDebuggerWithID (%" PRIu64 ")", 6790b57cec5SDimitry Andric m_debugger.GetID()); 6800b57cec5SDimitry Andric run_string.PutCString("')"); 6810b57cec5SDimitry Andric } 6820b57cec5SDimitry Andric 6830b57cec5SDimitry Andric PyRun_SimpleString(run_string.GetData()); 6840b57cec5SDimitry Andric run_string.Clear(); 6850b57cec5SDimitry Andric 6860b57cec5SDimitry Andric PythonDictionary &sys_module_dict = GetSysModuleDictionary(); 6870b57cec5SDimitry Andric if (sys_module_dict.IsValid()) { 6889dba64beSDimitry Andric lldb::FileSP top_in_sp; 6899dba64beSDimitry Andric lldb::StreamFileSP top_out_sp, top_err_sp; 6909dba64beSDimitry Andric if (!in_sp || !out_sp || !err_sp || !*in_sp || !*out_sp || !*err_sp) 6919dba64beSDimitry Andric m_debugger.AdoptTopIOHandlerFilesIfInvalid(top_in_sp, top_out_sp, 6929dba64beSDimitry Andric top_err_sp); 6930b57cec5SDimitry Andric 6940b57cec5SDimitry Andric if (on_entry_flags & Locker::NoSTDIN) { 6950b57cec5SDimitry Andric m_saved_stdin.Reset(); 6960b57cec5SDimitry Andric } else { 6979dba64beSDimitry Andric if (!SetStdHandle(in_sp, "stdin", m_saved_stdin, "r")) { 6989dba64beSDimitry Andric if (top_in_sp) 6999dba64beSDimitry Andric SetStdHandle(top_in_sp, "stdin", m_saved_stdin, "r"); 7000b57cec5SDimitry Andric } 7010b57cec5SDimitry Andric } 7020b57cec5SDimitry Andric 7039dba64beSDimitry Andric if (!SetStdHandle(out_sp, "stdout", m_saved_stdout, "w")) { 7049dba64beSDimitry Andric if (top_out_sp) 7059dba64beSDimitry Andric SetStdHandle(top_out_sp->GetFileSP(), "stdout", m_saved_stdout, "w"); 7060b57cec5SDimitry Andric } 7070b57cec5SDimitry Andric 7089dba64beSDimitry Andric if (!SetStdHandle(err_sp, "stderr", m_saved_stderr, "w")) { 7099dba64beSDimitry Andric if (top_err_sp) 7109dba64beSDimitry Andric SetStdHandle(top_err_sp->GetFileSP(), "stderr", m_saved_stderr, "w"); 7110b57cec5SDimitry Andric } 7120b57cec5SDimitry Andric } 7130b57cec5SDimitry Andric 7140b57cec5SDimitry Andric if (PyErr_Occurred()) 7150b57cec5SDimitry Andric PyErr_Clear(); 7160b57cec5SDimitry Andric 7170b57cec5SDimitry Andric return true; 7180b57cec5SDimitry Andric } 7190b57cec5SDimitry Andric 7209dba64beSDimitry Andric PythonModule &ScriptInterpreterPythonImpl::GetMainModule() { 7210b57cec5SDimitry Andric if (!m_main_module.IsValid()) 7229dba64beSDimitry Andric m_main_module = unwrapIgnoringErrors(PythonModule::Import("__main__")); 7230b57cec5SDimitry Andric return m_main_module; 7240b57cec5SDimitry Andric } 7250b57cec5SDimitry Andric 7260b57cec5SDimitry Andric PythonDictionary &ScriptInterpreterPythonImpl::GetSessionDictionary() { 7270b57cec5SDimitry Andric if (m_session_dict.IsValid()) 7280b57cec5SDimitry Andric return m_session_dict; 7290b57cec5SDimitry Andric 7300b57cec5SDimitry Andric PythonObject &main_module = GetMainModule(); 7310b57cec5SDimitry Andric if (!main_module.IsValid()) 7320b57cec5SDimitry Andric return m_session_dict; 7330b57cec5SDimitry Andric 7340b57cec5SDimitry Andric PythonDictionary main_dict(PyRefType::Borrowed, 7350b57cec5SDimitry Andric PyModule_GetDict(main_module.get())); 7360b57cec5SDimitry Andric if (!main_dict.IsValid()) 7370b57cec5SDimitry Andric return m_session_dict; 7380b57cec5SDimitry Andric 7399dba64beSDimitry Andric m_session_dict = unwrapIgnoringErrors( 7409dba64beSDimitry Andric As<PythonDictionary>(main_dict.GetItem(m_dictionary_name))); 7410b57cec5SDimitry Andric return m_session_dict; 7420b57cec5SDimitry Andric } 7430b57cec5SDimitry Andric 7440b57cec5SDimitry Andric PythonDictionary &ScriptInterpreterPythonImpl::GetSysModuleDictionary() { 7450b57cec5SDimitry Andric if (m_sys_module_dict.IsValid()) 7460b57cec5SDimitry Andric return m_sys_module_dict; 7479dba64beSDimitry Andric PythonModule sys_module = unwrapIgnoringErrors(PythonModule::Import("sys")); 7489dba64beSDimitry Andric m_sys_module_dict = sys_module.GetDictionary(); 7490b57cec5SDimitry Andric return m_sys_module_dict; 7500b57cec5SDimitry Andric } 7510b57cec5SDimitry Andric 752480093f4SDimitry Andric llvm::Expected<unsigned> 753480093f4SDimitry Andric ScriptInterpreterPythonImpl::GetMaxPositionalArgumentsForCallable( 754480093f4SDimitry Andric const llvm::StringRef &callable_name) { 755480093f4SDimitry Andric if (callable_name.empty()) { 756480093f4SDimitry Andric return llvm::createStringError( 757480093f4SDimitry Andric llvm::inconvertibleErrorCode(), 758480093f4SDimitry Andric "called with empty callable name."); 759480093f4SDimitry Andric } 760480093f4SDimitry Andric Locker py_lock(this, Locker::AcquireLock | 761480093f4SDimitry Andric Locker::InitSession | 762480093f4SDimitry Andric Locker::NoSTDIN); 763480093f4SDimitry Andric auto dict = PythonModule::MainModule() 764480093f4SDimitry Andric .ResolveName<PythonDictionary>(m_dictionary_name); 765480093f4SDimitry Andric auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>( 766480093f4SDimitry Andric callable_name, dict); 767480093f4SDimitry Andric if (!pfunc.IsAllocated()) { 768480093f4SDimitry Andric return llvm::createStringError( 769480093f4SDimitry Andric llvm::inconvertibleErrorCode(), 770480093f4SDimitry Andric "can't find callable: %s", callable_name.str().c_str()); 771480093f4SDimitry Andric } 772480093f4SDimitry Andric llvm::Expected<PythonCallable::ArgInfo> arg_info = pfunc.GetArgInfo(); 773480093f4SDimitry Andric if (!arg_info) 774480093f4SDimitry Andric return arg_info.takeError(); 775480093f4SDimitry Andric return arg_info.get().max_positional_args; 776480093f4SDimitry Andric } 777480093f4SDimitry Andric 7780b57cec5SDimitry Andric static std::string GenerateUniqueName(const char *base_name_wanted, 7790b57cec5SDimitry Andric uint32_t &functions_counter, 7800b57cec5SDimitry Andric const void *name_token = nullptr) { 7810b57cec5SDimitry Andric StreamString sstr; 7820b57cec5SDimitry Andric 7830b57cec5SDimitry Andric if (!base_name_wanted) 7840b57cec5SDimitry Andric return std::string(); 7850b57cec5SDimitry Andric 7860b57cec5SDimitry Andric if (!name_token) 7870b57cec5SDimitry Andric sstr.Printf("%s_%d", base_name_wanted, functions_counter++); 7880b57cec5SDimitry Andric else 7890b57cec5SDimitry Andric sstr.Printf("%s_%p", base_name_wanted, name_token); 7900b57cec5SDimitry Andric 7915ffd83dbSDimitry Andric return std::string(sstr.GetString()); 7920b57cec5SDimitry Andric } 7930b57cec5SDimitry Andric 7940b57cec5SDimitry Andric bool ScriptInterpreterPythonImpl::GetEmbeddedInterpreterModuleObjects() { 7950b57cec5SDimitry Andric if (m_run_one_line_function.IsValid()) 7960b57cec5SDimitry Andric return true; 7970b57cec5SDimitry Andric 7980b57cec5SDimitry Andric PythonObject module(PyRefType::Borrowed, 7990b57cec5SDimitry Andric PyImport_AddModule("lldb.embedded_interpreter")); 8000b57cec5SDimitry Andric if (!module.IsValid()) 8010b57cec5SDimitry Andric return false; 8020b57cec5SDimitry Andric 8030b57cec5SDimitry Andric PythonDictionary module_dict(PyRefType::Borrowed, 8040b57cec5SDimitry Andric PyModule_GetDict(module.get())); 8050b57cec5SDimitry Andric if (!module_dict.IsValid()) 8060b57cec5SDimitry Andric return false; 8070b57cec5SDimitry Andric 8080b57cec5SDimitry Andric m_run_one_line_function = 8090b57cec5SDimitry Andric module_dict.GetItemForKey(PythonString("run_one_line")); 8100b57cec5SDimitry Andric m_run_one_line_str_global = 8110b57cec5SDimitry Andric module_dict.GetItemForKey(PythonString("g_run_one_line_str")); 8120b57cec5SDimitry Andric return m_run_one_line_function.IsValid(); 8130b57cec5SDimitry Andric } 8140b57cec5SDimitry Andric 8150b57cec5SDimitry Andric bool ScriptInterpreterPythonImpl::ExecuteOneLine( 8160b57cec5SDimitry Andric llvm::StringRef command, CommandReturnObject *result, 8170b57cec5SDimitry Andric const ExecuteScriptOptions &options) { 8180b57cec5SDimitry Andric std::string command_str = command.str(); 8190b57cec5SDimitry Andric 8200b57cec5SDimitry Andric if (!m_valid_session) 8210b57cec5SDimitry Andric return false; 8220b57cec5SDimitry Andric 8230b57cec5SDimitry Andric if (!command.empty()) { 8240b57cec5SDimitry Andric // We want to call run_one_line, passing in the dictionary and the command 8250b57cec5SDimitry Andric // string. We cannot do this through PyRun_SimpleString here because the 8260b57cec5SDimitry Andric // command string may contain escaped characters, and putting it inside 8270b57cec5SDimitry Andric // another string to pass to PyRun_SimpleString messes up the escaping. So 8280b57cec5SDimitry Andric // we use the following more complicated method to pass the command string 8290b57cec5SDimitry Andric // directly down to Python. 8305ffd83dbSDimitry Andric llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>> 8315ffd83dbSDimitry Andric io_redirect_or_error = ScriptInterpreterIORedirect::Create( 8325ffd83dbSDimitry Andric options.GetEnableIO(), m_debugger, result); 8335ffd83dbSDimitry Andric if (!io_redirect_or_error) { 8345ffd83dbSDimitry Andric if (result) 8355ffd83dbSDimitry Andric result->AppendErrorWithFormatv( 8365ffd83dbSDimitry Andric "failed to redirect I/O: {0}\n", 8375ffd83dbSDimitry Andric llvm::fmt_consume(io_redirect_or_error.takeError())); 8385ffd83dbSDimitry Andric else 8395ffd83dbSDimitry Andric llvm::consumeError(io_redirect_or_error.takeError()); 8409dba64beSDimitry Andric return false; 8419dba64beSDimitry Andric } 8425ffd83dbSDimitry Andric 8435ffd83dbSDimitry Andric ScriptInterpreterIORedirect &io_redirect = **io_redirect_or_error; 8440b57cec5SDimitry Andric 8450b57cec5SDimitry Andric bool success = false; 8460b57cec5SDimitry Andric { 8470b57cec5SDimitry Andric // WARNING! It's imperative that this RAII scope be as tight as 8480b57cec5SDimitry Andric // possible. In particular, the scope must end *before* we try to join 8490b57cec5SDimitry Andric // the read thread. The reason for this is that a pre-requisite for 8500b57cec5SDimitry Andric // joining the read thread is that we close the write handle (to break 8510b57cec5SDimitry Andric // the pipe and cause it to wake up and exit). But acquiring the GIL as 8520b57cec5SDimitry Andric // below will redirect Python's stdio to use this same handle. If we 8530b57cec5SDimitry Andric // close the handle while Python is still using it, bad things will 8540b57cec5SDimitry Andric // happen. 8550b57cec5SDimitry Andric Locker locker( 8560b57cec5SDimitry Andric this, 8570b57cec5SDimitry Andric Locker::AcquireLock | Locker::InitSession | 8580b57cec5SDimitry Andric (options.GetSetLLDBGlobals() ? Locker::InitGlobals : 0) | 8590b57cec5SDimitry Andric ((result && result->GetInteractive()) ? 0 : Locker::NoSTDIN), 8605ffd83dbSDimitry Andric Locker::FreeAcquiredLock | Locker::TearDownSession, 8615ffd83dbSDimitry Andric io_redirect.GetInputFile(), io_redirect.GetOutputFile(), 8625ffd83dbSDimitry Andric io_redirect.GetErrorFile()); 8630b57cec5SDimitry Andric 8640b57cec5SDimitry Andric // Find the correct script interpreter dictionary in the main module. 8650b57cec5SDimitry Andric PythonDictionary &session_dict = GetSessionDictionary(); 8660b57cec5SDimitry Andric if (session_dict.IsValid()) { 8670b57cec5SDimitry Andric if (GetEmbeddedInterpreterModuleObjects()) { 8680b57cec5SDimitry Andric if (PyCallable_Check(m_run_one_line_function.get())) { 8690b57cec5SDimitry Andric PythonObject pargs( 8700b57cec5SDimitry Andric PyRefType::Owned, 8710b57cec5SDimitry Andric Py_BuildValue("(Os)", session_dict.get(), command_str.c_str())); 8720b57cec5SDimitry Andric if (pargs.IsValid()) { 8730b57cec5SDimitry Andric PythonObject return_value( 8740b57cec5SDimitry Andric PyRefType::Owned, 8750b57cec5SDimitry Andric PyObject_CallObject(m_run_one_line_function.get(), 8760b57cec5SDimitry Andric pargs.get())); 8770b57cec5SDimitry Andric if (return_value.IsValid()) 8780b57cec5SDimitry Andric success = true; 8790b57cec5SDimitry Andric else if (options.GetMaskoutErrors() && PyErr_Occurred()) { 8800b57cec5SDimitry Andric PyErr_Print(); 8810b57cec5SDimitry Andric PyErr_Clear(); 8820b57cec5SDimitry Andric } 8830b57cec5SDimitry Andric } 8840b57cec5SDimitry Andric } 8850b57cec5SDimitry Andric } 8860b57cec5SDimitry Andric } 8870b57cec5SDimitry Andric 8885ffd83dbSDimitry Andric io_redirect.Flush(); 8890b57cec5SDimitry Andric } 8900b57cec5SDimitry Andric 8910b57cec5SDimitry Andric if (success) 8920b57cec5SDimitry Andric return true; 8930b57cec5SDimitry Andric 8940b57cec5SDimitry Andric // The one-liner failed. Append the error message. 8950b57cec5SDimitry Andric if (result) { 8960b57cec5SDimitry Andric result->AppendErrorWithFormat( 8970b57cec5SDimitry Andric "python failed attempting to evaluate '%s'\n", command_str.c_str()); 8980b57cec5SDimitry Andric } 8990b57cec5SDimitry Andric return false; 9000b57cec5SDimitry Andric } 9010b57cec5SDimitry Andric 9020b57cec5SDimitry Andric if (result) 9030b57cec5SDimitry Andric result->AppendError("empty command passed to python\n"); 9040b57cec5SDimitry Andric return false; 9050b57cec5SDimitry Andric } 9060b57cec5SDimitry Andric 9070b57cec5SDimitry Andric void ScriptInterpreterPythonImpl::ExecuteInterpreterLoop() { 908e8d8bef9SDimitry Andric LLDB_SCOPED_TIMER(); 9090b57cec5SDimitry Andric 9100b57cec5SDimitry Andric Debugger &debugger = m_debugger; 9110b57cec5SDimitry Andric 9120b57cec5SDimitry Andric // At the moment, the only time the debugger does not have an input file 9130b57cec5SDimitry Andric // handle is when this is called directly from Python, in which case it is 9140b57cec5SDimitry Andric // both dangerous and unnecessary (not to mention confusing) to try to embed 9150b57cec5SDimitry Andric // a running interpreter loop inside the already running Python interpreter 9160b57cec5SDimitry Andric // loop, so we won't do it. 9170b57cec5SDimitry Andric 9189dba64beSDimitry Andric if (!debugger.GetInputFile().IsValid()) 9190b57cec5SDimitry Andric return; 9200b57cec5SDimitry Andric 9210b57cec5SDimitry Andric IOHandlerSP io_handler_sp(new IOHandlerPythonInterpreter(debugger, this)); 9220b57cec5SDimitry Andric if (io_handler_sp) { 9235ffd83dbSDimitry Andric debugger.RunIOHandlerAsync(io_handler_sp); 9240b57cec5SDimitry Andric } 9250b57cec5SDimitry Andric } 9260b57cec5SDimitry Andric 9270b57cec5SDimitry Andric bool ScriptInterpreterPythonImpl::Interrupt() { 92804eeddc0SDimitry Andric #if LLDB_USE_PYTHON_SET_INTERRUPT 92904eeddc0SDimitry Andric // If the interpreter isn't evaluating any Python at the moment then return 93004eeddc0SDimitry Andric // false to signal that this function didn't handle the interrupt and the 93104eeddc0SDimitry Andric // next component should try handling it. 93204eeddc0SDimitry Andric if (!IsExecutingPython()) 93304eeddc0SDimitry Andric return false; 93404eeddc0SDimitry Andric 93504eeddc0SDimitry Andric // Tell Python that it should pretend to have received a SIGINT. 93604eeddc0SDimitry Andric PyErr_SetInterrupt(); 93704eeddc0SDimitry Andric // PyErr_SetInterrupt has no way to return an error so we can only pretend the 93804eeddc0SDimitry Andric // signal got successfully handled and return true. 93904eeddc0SDimitry Andric // Python 3.10 introduces PyErr_SetInterruptEx that could return an error, but 94004eeddc0SDimitry Andric // the error handling is limited to checking the arguments which would be 94104eeddc0SDimitry Andric // just our (hardcoded) input signal code SIGINT, so that's not useful at all. 94204eeddc0SDimitry Andric return true; 94304eeddc0SDimitry Andric #else 94481ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Script); 9450b57cec5SDimitry Andric 9460b57cec5SDimitry Andric if (IsExecutingPython()) { 9470b57cec5SDimitry Andric PyThreadState *state = PyThreadState_GET(); 9480b57cec5SDimitry Andric if (!state) 9490b57cec5SDimitry Andric state = GetThreadState(); 9500b57cec5SDimitry Andric if (state) { 9510b57cec5SDimitry Andric long tid = state->thread_id; 9520b57cec5SDimitry Andric PyThreadState_Swap(state); 9530b57cec5SDimitry Andric int num_threads = PyThreadState_SetAsyncExc(tid, PyExc_KeyboardInterrupt); 9549dba64beSDimitry Andric LLDB_LOGF(log, 9559dba64beSDimitry Andric "ScriptInterpreterPythonImpl::Interrupt() sending " 9560b57cec5SDimitry Andric "PyExc_KeyboardInterrupt (tid = %li, num_threads = %i)...", 9570b57cec5SDimitry Andric tid, num_threads); 9580b57cec5SDimitry Andric return true; 9590b57cec5SDimitry Andric } 9600b57cec5SDimitry Andric } 9619dba64beSDimitry Andric LLDB_LOGF(log, 9620b57cec5SDimitry Andric "ScriptInterpreterPythonImpl::Interrupt() python code not running, " 9630b57cec5SDimitry Andric "can't interrupt"); 9640b57cec5SDimitry Andric return false; 96504eeddc0SDimitry Andric #endif 9660b57cec5SDimitry Andric } 9679dba64beSDimitry Andric 9680b57cec5SDimitry Andric bool ScriptInterpreterPythonImpl::ExecuteOneLineWithReturn( 9690b57cec5SDimitry Andric llvm::StringRef in_string, ScriptInterpreter::ScriptReturnType return_type, 9700b57cec5SDimitry Andric void *ret_value, const ExecuteScriptOptions &options) { 9710b57cec5SDimitry Andric 972fe6060f1SDimitry Andric llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>> 973fe6060f1SDimitry Andric io_redirect_or_error = ScriptInterpreterIORedirect::Create( 974fe6060f1SDimitry Andric options.GetEnableIO(), m_debugger, /*result=*/nullptr); 975fe6060f1SDimitry Andric 976fe6060f1SDimitry Andric if (!io_redirect_or_error) { 977fe6060f1SDimitry Andric llvm::consumeError(io_redirect_or_error.takeError()); 978fe6060f1SDimitry Andric return false; 979fe6060f1SDimitry Andric } 980fe6060f1SDimitry Andric 981fe6060f1SDimitry Andric ScriptInterpreterIORedirect &io_redirect = **io_redirect_or_error; 982fe6060f1SDimitry Andric 9830b57cec5SDimitry Andric Locker locker(this, 9840b57cec5SDimitry Andric Locker::AcquireLock | Locker::InitSession | 9850b57cec5SDimitry Andric (options.GetSetLLDBGlobals() ? Locker::InitGlobals : 0) | 9860b57cec5SDimitry Andric Locker::NoSTDIN, 987fe6060f1SDimitry Andric Locker::FreeAcquiredLock | Locker::TearDownSession, 988fe6060f1SDimitry Andric io_redirect.GetInputFile(), io_redirect.GetOutputFile(), 989fe6060f1SDimitry Andric io_redirect.GetErrorFile()); 9900b57cec5SDimitry Andric 9919dba64beSDimitry Andric PythonModule &main_module = GetMainModule(); 9929dba64beSDimitry Andric PythonDictionary globals = main_module.GetDictionary(); 9930b57cec5SDimitry Andric 9940b57cec5SDimitry Andric PythonDictionary locals = GetSessionDictionary(); 9959dba64beSDimitry Andric if (!locals.IsValid()) 9969dba64beSDimitry Andric locals = unwrapIgnoringErrors( 9979dba64beSDimitry Andric As<PythonDictionary>(globals.GetAttribute(m_dictionary_name))); 9980b57cec5SDimitry Andric if (!locals.IsValid()) 9990b57cec5SDimitry Andric locals = globals; 10000b57cec5SDimitry Andric 10019dba64beSDimitry Andric Expected<PythonObject> maybe_py_return = 10029dba64beSDimitry Andric runStringOneLine(in_string, globals, locals); 10030b57cec5SDimitry Andric 10049dba64beSDimitry Andric if (!maybe_py_return) { 10059dba64beSDimitry Andric llvm::handleAllErrors( 10069dba64beSDimitry Andric maybe_py_return.takeError(), 10079dba64beSDimitry Andric [&](PythonException &E) { 10089dba64beSDimitry Andric E.Restore(); 10099dba64beSDimitry Andric if (options.GetMaskoutErrors()) { 10109dba64beSDimitry Andric if (E.Matches(PyExc_SyntaxError)) { 10119dba64beSDimitry Andric PyErr_Print(); 10120b57cec5SDimitry Andric } 10139dba64beSDimitry Andric PyErr_Clear(); 10149dba64beSDimitry Andric } 10159dba64beSDimitry Andric }, 10169dba64beSDimitry Andric [](const llvm::ErrorInfoBase &E) {}); 10179dba64beSDimitry Andric return false; 10180b57cec5SDimitry Andric } 10190b57cec5SDimitry Andric 10209dba64beSDimitry Andric PythonObject py_return = std::move(maybe_py_return.get()); 10219dba64beSDimitry Andric assert(py_return.IsValid()); 10229dba64beSDimitry Andric 10230b57cec5SDimitry Andric switch (return_type) { 10240b57cec5SDimitry Andric case eScriptReturnTypeCharPtr: // "char *" 10250b57cec5SDimitry Andric { 10260b57cec5SDimitry Andric const char format[3] = "s#"; 10279dba64beSDimitry Andric return PyArg_Parse(py_return.get(), format, (char **)ret_value); 10280b57cec5SDimitry Andric } 10290b57cec5SDimitry Andric case eScriptReturnTypeCharStrOrNone: // char* or NULL if py_return == 10300b57cec5SDimitry Andric // Py_None 10310b57cec5SDimitry Andric { 10320b57cec5SDimitry Andric const char format[3] = "z"; 10339dba64beSDimitry Andric return PyArg_Parse(py_return.get(), format, (char **)ret_value); 10340b57cec5SDimitry Andric } 10350b57cec5SDimitry Andric case eScriptReturnTypeBool: { 10360b57cec5SDimitry Andric const char format[2] = "b"; 10379dba64beSDimitry Andric return PyArg_Parse(py_return.get(), format, (bool *)ret_value); 10380b57cec5SDimitry Andric } 10390b57cec5SDimitry Andric case eScriptReturnTypeShortInt: { 10400b57cec5SDimitry Andric const char format[2] = "h"; 10419dba64beSDimitry Andric return PyArg_Parse(py_return.get(), format, (short *)ret_value); 10420b57cec5SDimitry Andric } 10430b57cec5SDimitry Andric case eScriptReturnTypeShortIntUnsigned: { 10440b57cec5SDimitry Andric const char format[2] = "H"; 10459dba64beSDimitry Andric return PyArg_Parse(py_return.get(), format, (unsigned short *)ret_value); 10460b57cec5SDimitry Andric } 10470b57cec5SDimitry Andric case eScriptReturnTypeInt: { 10480b57cec5SDimitry Andric const char format[2] = "i"; 10499dba64beSDimitry Andric return PyArg_Parse(py_return.get(), format, (int *)ret_value); 10500b57cec5SDimitry Andric } 10510b57cec5SDimitry Andric case eScriptReturnTypeIntUnsigned: { 10520b57cec5SDimitry Andric const char format[2] = "I"; 10539dba64beSDimitry Andric return PyArg_Parse(py_return.get(), format, (unsigned int *)ret_value); 10540b57cec5SDimitry Andric } 10550b57cec5SDimitry Andric case eScriptReturnTypeLongInt: { 10560b57cec5SDimitry Andric const char format[2] = "l"; 10579dba64beSDimitry Andric return PyArg_Parse(py_return.get(), format, (long *)ret_value); 10580b57cec5SDimitry Andric } 10590b57cec5SDimitry Andric case eScriptReturnTypeLongIntUnsigned: { 10600b57cec5SDimitry Andric const char format[2] = "k"; 10619dba64beSDimitry Andric return PyArg_Parse(py_return.get(), format, (unsigned long *)ret_value); 10620b57cec5SDimitry Andric } 10630b57cec5SDimitry Andric case eScriptReturnTypeLongLong: { 10640b57cec5SDimitry Andric const char format[2] = "L"; 10659dba64beSDimitry Andric return PyArg_Parse(py_return.get(), format, (long long *)ret_value); 10660b57cec5SDimitry Andric } 10670b57cec5SDimitry Andric case eScriptReturnTypeLongLongUnsigned: { 10680b57cec5SDimitry Andric const char format[2] = "K"; 10699dba64beSDimitry Andric return PyArg_Parse(py_return.get(), format, 10709dba64beSDimitry Andric (unsigned long long *)ret_value); 10710b57cec5SDimitry Andric } 10720b57cec5SDimitry Andric case eScriptReturnTypeFloat: { 10730b57cec5SDimitry Andric const char format[2] = "f"; 10749dba64beSDimitry Andric return PyArg_Parse(py_return.get(), format, (float *)ret_value); 10750b57cec5SDimitry Andric } 10760b57cec5SDimitry Andric case eScriptReturnTypeDouble: { 10770b57cec5SDimitry Andric const char format[2] = "d"; 10789dba64beSDimitry Andric return PyArg_Parse(py_return.get(), format, (double *)ret_value); 10790b57cec5SDimitry Andric } 10800b57cec5SDimitry Andric case eScriptReturnTypeChar: { 10810b57cec5SDimitry Andric const char format[2] = "c"; 10829dba64beSDimitry Andric return PyArg_Parse(py_return.get(), format, (char *)ret_value); 10830b57cec5SDimitry Andric } 10840b57cec5SDimitry Andric case eScriptReturnTypeOpaqueObject: { 10859dba64beSDimitry Andric *((PyObject **)ret_value) = py_return.release(); 10869dba64beSDimitry Andric return true; 10870b57cec5SDimitry Andric } 10880b57cec5SDimitry Andric } 1089480093f4SDimitry Andric llvm_unreachable("Fully covered switch!"); 10900b57cec5SDimitry Andric } 10910b57cec5SDimitry Andric 10920b57cec5SDimitry Andric Status ScriptInterpreterPythonImpl::ExecuteMultipleLines( 10930b57cec5SDimitry Andric const char *in_string, const ExecuteScriptOptions &options) { 10949dba64beSDimitry Andric 10959dba64beSDimitry Andric if (in_string == nullptr) 10969dba64beSDimitry Andric return Status(); 10970b57cec5SDimitry Andric 1098fe6060f1SDimitry Andric llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>> 1099fe6060f1SDimitry Andric io_redirect_or_error = ScriptInterpreterIORedirect::Create( 1100fe6060f1SDimitry Andric options.GetEnableIO(), m_debugger, /*result=*/nullptr); 1101fe6060f1SDimitry Andric 1102fe6060f1SDimitry Andric if (!io_redirect_or_error) 1103fe6060f1SDimitry Andric return Status(io_redirect_or_error.takeError()); 1104fe6060f1SDimitry Andric 1105fe6060f1SDimitry Andric ScriptInterpreterIORedirect &io_redirect = **io_redirect_or_error; 1106fe6060f1SDimitry Andric 11070b57cec5SDimitry Andric Locker locker(this, 11080b57cec5SDimitry Andric Locker::AcquireLock | Locker::InitSession | 11090b57cec5SDimitry Andric (options.GetSetLLDBGlobals() ? Locker::InitGlobals : 0) | 11100b57cec5SDimitry Andric Locker::NoSTDIN, 1111fe6060f1SDimitry Andric Locker::FreeAcquiredLock | Locker::TearDownSession, 1112fe6060f1SDimitry Andric io_redirect.GetInputFile(), io_redirect.GetOutputFile(), 1113fe6060f1SDimitry Andric io_redirect.GetErrorFile()); 11140b57cec5SDimitry Andric 11159dba64beSDimitry Andric PythonModule &main_module = GetMainModule(); 11169dba64beSDimitry Andric PythonDictionary globals = main_module.GetDictionary(); 11170b57cec5SDimitry Andric 11180b57cec5SDimitry Andric PythonDictionary locals = GetSessionDictionary(); 11190b57cec5SDimitry Andric if (!locals.IsValid()) 11209dba64beSDimitry Andric locals = unwrapIgnoringErrors( 11219dba64beSDimitry Andric As<PythonDictionary>(globals.GetAttribute(m_dictionary_name))); 11220b57cec5SDimitry Andric if (!locals.IsValid()) 11230b57cec5SDimitry Andric locals = globals; 11240b57cec5SDimitry Andric 11259dba64beSDimitry Andric Expected<PythonObject> return_value = 11269dba64beSDimitry Andric runStringMultiLine(in_string, globals, locals); 11270b57cec5SDimitry Andric 11289dba64beSDimitry Andric if (!return_value) { 11299dba64beSDimitry Andric llvm::Error error = 11309dba64beSDimitry Andric llvm::handleErrors(return_value.takeError(), [&](PythonException &E) { 11319dba64beSDimitry Andric llvm::Error error = llvm::createStringError( 11329dba64beSDimitry Andric llvm::inconvertibleErrorCode(), E.ReadBacktrace()); 11339dba64beSDimitry Andric if (!options.GetMaskoutErrors()) 11349dba64beSDimitry Andric E.Restore(); 11350b57cec5SDimitry Andric return error; 11369dba64beSDimitry Andric }); 11379dba64beSDimitry Andric return Status(std::move(error)); 11389dba64beSDimitry Andric } 11399dba64beSDimitry Andric 11409dba64beSDimitry Andric return Status(); 11410b57cec5SDimitry Andric } 11420b57cec5SDimitry Andric 11430b57cec5SDimitry Andric void ScriptInterpreterPythonImpl::CollectDataForBreakpointCommandCallback( 1144fe6060f1SDimitry Andric std::vector<std::reference_wrapper<BreakpointOptions>> &bp_options_vec, 11450b57cec5SDimitry Andric CommandReturnObject &result) { 11460b57cec5SDimitry Andric m_active_io_handler = eIOHandlerBreakpoint; 11470b57cec5SDimitry Andric m_debugger.GetCommandInterpreter().GetPythonCommandsFromIOHandler( 1148480093f4SDimitry Andric " ", *this, &bp_options_vec); 11490b57cec5SDimitry Andric } 11500b57cec5SDimitry Andric 11510b57cec5SDimitry Andric void ScriptInterpreterPythonImpl::CollectDataForWatchpointCommandCallback( 11520b57cec5SDimitry Andric WatchpointOptions *wp_options, CommandReturnObject &result) { 11530b57cec5SDimitry Andric m_active_io_handler = eIOHandlerWatchpoint; 11540b57cec5SDimitry Andric m_debugger.GetCommandInterpreter().GetPythonCommandsFromIOHandler( 1155480093f4SDimitry Andric " ", *this, wp_options); 11560b57cec5SDimitry Andric } 11570b57cec5SDimitry Andric 1158480093f4SDimitry Andric Status ScriptInterpreterPythonImpl::SetBreakpointCommandCallbackFunction( 1159fe6060f1SDimitry Andric BreakpointOptions &bp_options, const char *function_name, 1160480093f4SDimitry Andric StructuredData::ObjectSP extra_args_sp) { 1161480093f4SDimitry Andric Status error; 11620b57cec5SDimitry Andric // For now just cons up a oneliner that calls the provided function. 1163*fe013be4SDimitry Andric std::string function_signature = function_name; 1164480093f4SDimitry Andric 1165480093f4SDimitry Andric llvm::Expected<unsigned> maybe_args = 1166480093f4SDimitry Andric GetMaxPositionalArgumentsForCallable(function_name); 1167480093f4SDimitry Andric if (!maybe_args) { 1168480093f4SDimitry Andric error.SetErrorStringWithFormat( 1169480093f4SDimitry Andric "could not get num args: %s", 1170480093f4SDimitry Andric llvm::toString(maybe_args.takeError()).c_str()); 1171480093f4SDimitry Andric return error; 1172480093f4SDimitry Andric } 1173480093f4SDimitry Andric size_t max_args = *maybe_args; 1174480093f4SDimitry Andric 1175480093f4SDimitry Andric bool uses_extra_args = false; 1176480093f4SDimitry Andric if (max_args >= 4) { 1177480093f4SDimitry Andric uses_extra_args = true; 1178*fe013be4SDimitry Andric function_signature += "(frame, bp_loc, extra_args, internal_dict)"; 1179480093f4SDimitry Andric } else if (max_args >= 3) { 1180480093f4SDimitry Andric if (extra_args_sp) { 1181480093f4SDimitry Andric error.SetErrorString("cannot pass extra_args to a three argument callback" 1182480093f4SDimitry Andric ); 1183480093f4SDimitry Andric return error; 1184480093f4SDimitry Andric } 1185480093f4SDimitry Andric uses_extra_args = false; 1186*fe013be4SDimitry Andric function_signature += "(frame, bp_loc, internal_dict)"; 1187480093f4SDimitry Andric } else { 1188480093f4SDimitry Andric error.SetErrorStringWithFormat("expected 3 or 4 argument " 1189480093f4SDimitry Andric "function, %s can only take %zu", 1190480093f4SDimitry Andric function_name, max_args); 1191480093f4SDimitry Andric return error; 1192480093f4SDimitry Andric } 1193480093f4SDimitry Andric 1194*fe013be4SDimitry Andric SetBreakpointCommandCallback(bp_options, function_signature.c_str(), 1195*fe013be4SDimitry Andric extra_args_sp, uses_extra_args, 1196*fe013be4SDimitry Andric /*is_callback=*/true); 1197480093f4SDimitry Andric return error; 11980b57cec5SDimitry Andric } 11990b57cec5SDimitry Andric 12000b57cec5SDimitry Andric Status ScriptInterpreterPythonImpl::SetBreakpointCommandCallback( 1201fe6060f1SDimitry Andric BreakpointOptions &bp_options, 12020b57cec5SDimitry Andric std::unique_ptr<BreakpointOptions::CommandData> &cmd_data_up) { 12030b57cec5SDimitry Andric Status error; 12040b57cec5SDimitry Andric error = GenerateBreakpointCommandCallbackData(cmd_data_up->user_source, 1205480093f4SDimitry Andric cmd_data_up->script_source, 1206*fe013be4SDimitry Andric /*has_extra_args=*/false, 1207*fe013be4SDimitry Andric /*is_callback=*/false); 12080b57cec5SDimitry Andric if (error.Fail()) { 12090b57cec5SDimitry Andric return error; 12100b57cec5SDimitry Andric } 12110b57cec5SDimitry Andric auto baton_sp = 12120b57cec5SDimitry Andric std::make_shared<BreakpointOptions::CommandBaton>(std::move(cmd_data_up)); 1213fe6060f1SDimitry Andric bp_options.SetCallback( 12140b57cec5SDimitry Andric ScriptInterpreterPythonImpl::BreakpointCallbackFunction, baton_sp); 12150b57cec5SDimitry Andric return error; 12160b57cec5SDimitry Andric } 12170b57cec5SDimitry Andric 12180b57cec5SDimitry Andric Status ScriptInterpreterPythonImpl::SetBreakpointCommandCallback( 1219*fe013be4SDimitry Andric BreakpointOptions &bp_options, const char *command_body_text, 1220*fe013be4SDimitry Andric bool is_callback) { 1221*fe013be4SDimitry Andric return SetBreakpointCommandCallback(bp_options, command_body_text, {}, 1222*fe013be4SDimitry Andric /*uses_extra_args=*/false, is_callback); 1223480093f4SDimitry Andric } 12240b57cec5SDimitry Andric 1225480093f4SDimitry Andric // Set a Python one-liner as the callback for the breakpoint. 1226480093f4SDimitry Andric Status ScriptInterpreterPythonImpl::SetBreakpointCommandCallback( 1227fe6060f1SDimitry Andric BreakpointOptions &bp_options, const char *command_body_text, 1228*fe013be4SDimitry Andric StructuredData::ObjectSP extra_args_sp, bool uses_extra_args, 1229*fe013be4SDimitry Andric bool is_callback) { 1230480093f4SDimitry Andric auto data_up = std::make_unique<CommandDataPython>(extra_args_sp); 12310b57cec5SDimitry Andric // Split the command_body_text into lines, and pass that to 12320b57cec5SDimitry Andric // GenerateBreakpointCommandCallbackData. That will wrap the body in an 12330b57cec5SDimitry Andric // auto-generated function, and return the function name in script_source. 12340b57cec5SDimitry Andric // That is what the callback will actually invoke. 12350b57cec5SDimitry Andric 12360b57cec5SDimitry Andric data_up->user_source.SplitIntoLines(command_body_text); 1237*fe013be4SDimitry Andric Status error = GenerateBreakpointCommandCallbackData( 1238*fe013be4SDimitry Andric data_up->user_source, data_up->script_source, uses_extra_args, 1239*fe013be4SDimitry Andric is_callback); 12400b57cec5SDimitry Andric if (error.Success()) { 12410b57cec5SDimitry Andric auto baton_sp = 12420b57cec5SDimitry Andric std::make_shared<BreakpointOptions::CommandBaton>(std::move(data_up)); 1243fe6060f1SDimitry Andric bp_options.SetCallback( 12440b57cec5SDimitry Andric ScriptInterpreterPythonImpl::BreakpointCallbackFunction, baton_sp); 12450b57cec5SDimitry Andric return error; 12465ffd83dbSDimitry Andric } 12470b57cec5SDimitry Andric return error; 12480b57cec5SDimitry Andric } 12490b57cec5SDimitry Andric 12500b57cec5SDimitry Andric // Set a Python one-liner as the callback for the watchpoint. 12510b57cec5SDimitry Andric void ScriptInterpreterPythonImpl::SetWatchpointCommandCallback( 1252*fe013be4SDimitry Andric WatchpointOptions *wp_options, const char *user_input, 1253*fe013be4SDimitry Andric bool is_callback) { 12549dba64beSDimitry Andric auto data_up = std::make_unique<WatchpointOptions::CommandData>(); 12550b57cec5SDimitry Andric 12560b57cec5SDimitry Andric // It's necessary to set both user_source and script_source to the oneliner. 12570b57cec5SDimitry Andric // The former is used to generate callback description (as in watchpoint 12580b57cec5SDimitry Andric // command list) while the latter is used for Python to interpret during the 12590b57cec5SDimitry Andric // actual callback. 12600b57cec5SDimitry Andric 1261*fe013be4SDimitry Andric data_up->user_source.AppendString(user_input); 1262*fe013be4SDimitry Andric data_up->script_source.assign(user_input); 12630b57cec5SDimitry Andric 1264*fe013be4SDimitry Andric if (GenerateWatchpointCommandCallbackData( 1265*fe013be4SDimitry Andric data_up->user_source, data_up->script_source, is_callback)) { 12660b57cec5SDimitry Andric auto baton_sp = 12670b57cec5SDimitry Andric std::make_shared<WatchpointOptions::CommandBaton>(std::move(data_up)); 12680b57cec5SDimitry Andric wp_options->SetCallback( 12690b57cec5SDimitry Andric ScriptInterpreterPythonImpl::WatchpointCallbackFunction, baton_sp); 12700b57cec5SDimitry Andric } 12710b57cec5SDimitry Andric } 12720b57cec5SDimitry Andric 12730b57cec5SDimitry Andric Status ScriptInterpreterPythonImpl::ExportFunctionDefinitionToInterpreter( 12740b57cec5SDimitry Andric StringList &function_def) { 12750b57cec5SDimitry Andric // Convert StringList to one long, newline delimited, const char *. 12760b57cec5SDimitry Andric std::string function_def_string(function_def.CopyList()); 12770b57cec5SDimitry Andric 12780b57cec5SDimitry Andric Status error = ExecuteMultipleLines( 12790b57cec5SDimitry Andric function_def_string.c_str(), 1280fe6060f1SDimitry Andric ExecuteScriptOptions().SetEnableIO(false)); 12810b57cec5SDimitry Andric return error; 12820b57cec5SDimitry Andric } 12830b57cec5SDimitry Andric 12840b57cec5SDimitry Andric Status ScriptInterpreterPythonImpl::GenerateFunction(const char *signature, 1285*fe013be4SDimitry Andric const StringList &input, 1286*fe013be4SDimitry Andric bool is_callback) { 12870b57cec5SDimitry Andric Status error; 12880b57cec5SDimitry Andric int num_lines = input.GetSize(); 12890b57cec5SDimitry Andric if (num_lines == 0) { 12900b57cec5SDimitry Andric error.SetErrorString("No input data."); 12910b57cec5SDimitry Andric return error; 12920b57cec5SDimitry Andric } 12930b57cec5SDimitry Andric 12940b57cec5SDimitry Andric if (!signature || *signature == 0) { 12950b57cec5SDimitry Andric error.SetErrorString("No output function name."); 12960b57cec5SDimitry Andric return error; 12970b57cec5SDimitry Andric } 12980b57cec5SDimitry Andric 12990b57cec5SDimitry Andric StreamString sstr; 13000b57cec5SDimitry Andric StringList auto_generated_function; 13010b57cec5SDimitry Andric auto_generated_function.AppendString(signature); 13020b57cec5SDimitry Andric auto_generated_function.AppendString( 13030b57cec5SDimitry Andric " global_dict = globals()"); // Grab the global dictionary 13040b57cec5SDimitry Andric auto_generated_function.AppendString( 13050b57cec5SDimitry Andric " new_keys = internal_dict.keys()"); // Make a list of keys in the 13060b57cec5SDimitry Andric // session dict 13070b57cec5SDimitry Andric auto_generated_function.AppendString( 13080b57cec5SDimitry Andric " old_keys = global_dict.keys()"); // Save list of keys in global dict 13090b57cec5SDimitry Andric auto_generated_function.AppendString( 13100b57cec5SDimitry Andric " global_dict.update(internal_dict)"); // Add the session dictionary 1311*fe013be4SDimitry Andric // to the global dictionary. 13120b57cec5SDimitry Andric 1313*fe013be4SDimitry Andric if (is_callback) { 1314*fe013be4SDimitry Andric // If the user input is a callback to a python function, make sure the input 1315*fe013be4SDimitry Andric // is only 1 line, otherwise appending the user input would break the 1316*fe013be4SDimitry Andric // generated wrapped function 1317*fe013be4SDimitry Andric if (num_lines == 1) { 1318*fe013be4SDimitry Andric sstr.Clear(); 1319*fe013be4SDimitry Andric sstr.Printf(" __return_val = %s", input.GetStringAtIndex(0)); 1320*fe013be4SDimitry Andric auto_generated_function.AppendString(sstr.GetData()); 1321*fe013be4SDimitry Andric } else { 1322*fe013be4SDimitry Andric return Status("ScriptInterpreterPythonImpl::GenerateFunction(is_callback=" 1323*fe013be4SDimitry Andric "true) = ERROR: python function is multiline."); 1324*fe013be4SDimitry Andric } 1325*fe013be4SDimitry Andric } else { 1326*fe013be4SDimitry Andric auto_generated_function.AppendString( 1327*fe013be4SDimitry Andric " __return_val = None"); // Initialize user callback return value. 1328*fe013be4SDimitry Andric auto_generated_function.AppendString( 1329*fe013be4SDimitry Andric " def __user_code():"); // Create a nested function that will wrap 1330*fe013be4SDimitry Andric // the user input. This is necessary to 1331*fe013be4SDimitry Andric // capture the return value of the user input 1332*fe013be4SDimitry Andric // and prevent early returns. 13330b57cec5SDimitry Andric for (int i = 0; i < num_lines; ++i) { 13340b57cec5SDimitry Andric sstr.Clear(); 13350b57cec5SDimitry Andric sstr.Printf(" %s", input.GetStringAtIndex(i)); 13360b57cec5SDimitry Andric auto_generated_function.AppendString(sstr.GetData()); 13370b57cec5SDimitry Andric } 13380b57cec5SDimitry Andric auto_generated_function.AppendString( 1339*fe013be4SDimitry Andric " __return_val = __user_code()"); // Call user code and capture 1340*fe013be4SDimitry Andric // return value 1341*fe013be4SDimitry Andric } 1342*fe013be4SDimitry Andric auto_generated_function.AppendString( 13430b57cec5SDimitry Andric " for key in new_keys:"); // Iterate over all the keys from session 13440b57cec5SDimitry Andric // dict 13450b57cec5SDimitry Andric auto_generated_function.AppendString( 13460b57cec5SDimitry Andric " internal_dict[key] = global_dict[key]"); // Update session dict 13470b57cec5SDimitry Andric // values 13480b57cec5SDimitry Andric auto_generated_function.AppendString( 13490b57cec5SDimitry Andric " if key not in old_keys:"); // If key was not originally in 13500b57cec5SDimitry Andric // global dict 13510b57cec5SDimitry Andric auto_generated_function.AppendString( 13520b57cec5SDimitry Andric " del global_dict[key]"); // ...then remove key/value from 13530b57cec5SDimitry Andric // global dict 1354*fe013be4SDimitry Andric auto_generated_function.AppendString( 1355*fe013be4SDimitry Andric " return __return_val"); // Return the user callback return value. 13560b57cec5SDimitry Andric 13570b57cec5SDimitry Andric // Verify that the results are valid Python. 13580b57cec5SDimitry Andric error = ExportFunctionDefinitionToInterpreter(auto_generated_function); 13590b57cec5SDimitry Andric 13600b57cec5SDimitry Andric return error; 13610b57cec5SDimitry Andric } 13620b57cec5SDimitry Andric 13630b57cec5SDimitry Andric bool ScriptInterpreterPythonImpl::GenerateTypeScriptFunction( 13640b57cec5SDimitry Andric StringList &user_input, std::string &output, const void *name_token) { 13650b57cec5SDimitry Andric static uint32_t num_created_functions = 0; 13660b57cec5SDimitry Andric user_input.RemoveBlankLines(); 13670b57cec5SDimitry Andric StreamString sstr; 13680b57cec5SDimitry Andric 13690b57cec5SDimitry Andric // Check to see if we have any data; if not, just return. 13700b57cec5SDimitry Andric if (user_input.GetSize() == 0) 13710b57cec5SDimitry Andric return false; 13720b57cec5SDimitry Andric 13730b57cec5SDimitry Andric // Take what the user wrote, wrap it all up inside one big auto-generated 13740b57cec5SDimitry Andric // Python function, passing in the ValueObject as parameter to the function. 13750b57cec5SDimitry Andric 13760b57cec5SDimitry Andric std::string auto_generated_function_name( 13770b57cec5SDimitry Andric GenerateUniqueName("lldb_autogen_python_type_print_func", 13780b57cec5SDimitry Andric num_created_functions, name_token)); 13790b57cec5SDimitry Andric sstr.Printf("def %s (valobj, internal_dict):", 13800b57cec5SDimitry Andric auto_generated_function_name.c_str()); 13810b57cec5SDimitry Andric 1382*fe013be4SDimitry Andric if (!GenerateFunction(sstr.GetData(), user_input, /*is_callback=*/false) 1383*fe013be4SDimitry Andric .Success()) 13840b57cec5SDimitry Andric return false; 13850b57cec5SDimitry Andric 13860b57cec5SDimitry Andric // Store the name of the auto-generated function to be called. 13870b57cec5SDimitry Andric output.assign(auto_generated_function_name); 13880b57cec5SDimitry Andric return true; 13890b57cec5SDimitry Andric } 13900b57cec5SDimitry Andric 13910b57cec5SDimitry Andric bool ScriptInterpreterPythonImpl::GenerateScriptAliasFunction( 13920b57cec5SDimitry Andric StringList &user_input, std::string &output) { 13930b57cec5SDimitry Andric static uint32_t num_created_functions = 0; 13940b57cec5SDimitry Andric user_input.RemoveBlankLines(); 13950b57cec5SDimitry Andric StreamString sstr; 13960b57cec5SDimitry Andric 13970b57cec5SDimitry Andric // Check to see if we have any data; if not, just return. 13980b57cec5SDimitry Andric if (user_input.GetSize() == 0) 13990b57cec5SDimitry Andric return false; 14000b57cec5SDimitry Andric 14010b57cec5SDimitry Andric std::string auto_generated_function_name(GenerateUniqueName( 14020b57cec5SDimitry Andric "lldb_autogen_python_cmd_alias_func", num_created_functions)); 14030b57cec5SDimitry Andric 1404bdd1243dSDimitry Andric sstr.Printf("def %s (debugger, args, exe_ctx, result, internal_dict):", 14050b57cec5SDimitry Andric auto_generated_function_name.c_str()); 14060b57cec5SDimitry Andric 1407*fe013be4SDimitry Andric if (!GenerateFunction(sstr.GetData(), user_input, /*is_callback=*/true) 1408*fe013be4SDimitry Andric .Success()) 14090b57cec5SDimitry Andric return false; 14100b57cec5SDimitry Andric 14110b57cec5SDimitry Andric // Store the name of the auto-generated function to be called. 14120b57cec5SDimitry Andric output.assign(auto_generated_function_name); 14130b57cec5SDimitry Andric return true; 14140b57cec5SDimitry Andric } 14150b57cec5SDimitry Andric 14160b57cec5SDimitry Andric bool ScriptInterpreterPythonImpl::GenerateTypeSynthClass( 14170b57cec5SDimitry Andric StringList &user_input, std::string &output, const void *name_token) { 14180b57cec5SDimitry Andric static uint32_t num_created_classes = 0; 14190b57cec5SDimitry Andric user_input.RemoveBlankLines(); 14200b57cec5SDimitry Andric int num_lines = user_input.GetSize(); 14210b57cec5SDimitry Andric StreamString sstr; 14220b57cec5SDimitry Andric 14230b57cec5SDimitry Andric // Check to see if we have any data; if not, just return. 14240b57cec5SDimitry Andric if (user_input.GetSize() == 0) 14250b57cec5SDimitry Andric return false; 14260b57cec5SDimitry Andric 14270b57cec5SDimitry Andric // Wrap all user input into a Python class 14280b57cec5SDimitry Andric 14290b57cec5SDimitry Andric std::string auto_generated_class_name(GenerateUniqueName( 14300b57cec5SDimitry Andric "lldb_autogen_python_type_synth_class", num_created_classes, name_token)); 14310b57cec5SDimitry Andric 14320b57cec5SDimitry Andric StringList auto_generated_class; 14330b57cec5SDimitry Andric 14340b57cec5SDimitry Andric // Create the function name & definition string. 14350b57cec5SDimitry Andric 14360b57cec5SDimitry Andric sstr.Printf("class %s:", auto_generated_class_name.c_str()); 14370b57cec5SDimitry Andric auto_generated_class.AppendString(sstr.GetString()); 14380b57cec5SDimitry Andric 14390b57cec5SDimitry Andric // Wrap everything up inside the class, increasing the indentation. we don't 14400b57cec5SDimitry Andric // need to play any fancy indentation tricks here because there is no 14410b57cec5SDimitry Andric // surrounding code whose indentation we need to honor 14420b57cec5SDimitry Andric for (int i = 0; i < num_lines; ++i) { 14430b57cec5SDimitry Andric sstr.Clear(); 14440b57cec5SDimitry Andric sstr.Printf(" %s", user_input.GetStringAtIndex(i)); 14450b57cec5SDimitry Andric auto_generated_class.AppendString(sstr.GetString()); 14460b57cec5SDimitry Andric } 14470b57cec5SDimitry Andric 14480b57cec5SDimitry Andric // Verify that the results are valid Python. (even though the method is 14490b57cec5SDimitry Andric // ExportFunctionDefinitionToInterpreter, a class will actually be exported) 14500b57cec5SDimitry Andric // (TODO: rename that method to ExportDefinitionToInterpreter) 14510b57cec5SDimitry Andric if (!ExportFunctionDefinitionToInterpreter(auto_generated_class).Success()) 14520b57cec5SDimitry Andric return false; 14530b57cec5SDimitry Andric 14540b57cec5SDimitry Andric // Store the name of the auto-generated class 14550b57cec5SDimitry Andric 14560b57cec5SDimitry Andric output.assign(auto_generated_class_name); 14570b57cec5SDimitry Andric return true; 14580b57cec5SDimitry Andric } 14590b57cec5SDimitry Andric 14600b57cec5SDimitry Andric StructuredData::GenericSP 14610b57cec5SDimitry Andric ScriptInterpreterPythonImpl::CreateFrameRecognizer(const char *class_name) { 14620b57cec5SDimitry Andric if (class_name == nullptr || class_name[0] == '\0') 14630b57cec5SDimitry Andric return StructuredData::GenericSP(); 14640b57cec5SDimitry Andric 146504eeddc0SDimitry Andric Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock); 1466*fe013be4SDimitry Andric PythonObject ret_val = SWIGBridge::LLDBSWIGPython_CreateFrameRecognizer( 146704eeddc0SDimitry Andric class_name, m_dictionary_name.c_str()); 14680b57cec5SDimitry Andric 146904eeddc0SDimitry Andric return StructuredData::GenericSP( 147004eeddc0SDimitry Andric new StructuredPythonObject(std::move(ret_val))); 14710b57cec5SDimitry Andric } 14720b57cec5SDimitry Andric 14730b57cec5SDimitry Andric lldb::ValueObjectListSP ScriptInterpreterPythonImpl::GetRecognizedArguments( 14740b57cec5SDimitry Andric const StructuredData::ObjectSP &os_plugin_object_sp, 14750b57cec5SDimitry Andric lldb::StackFrameSP frame_sp) { 14760b57cec5SDimitry Andric Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock); 14770b57cec5SDimitry Andric 14780b57cec5SDimitry Andric if (!os_plugin_object_sp) 14790b57cec5SDimitry Andric return ValueObjectListSP(); 14800b57cec5SDimitry Andric 14810b57cec5SDimitry Andric StructuredData::Generic *generic = os_plugin_object_sp->GetAsGeneric(); 14820b57cec5SDimitry Andric if (!generic) 14830b57cec5SDimitry Andric return nullptr; 14840b57cec5SDimitry Andric 14850b57cec5SDimitry Andric PythonObject implementor(PyRefType::Borrowed, 14860b57cec5SDimitry Andric (PyObject *)generic->GetValue()); 14870b57cec5SDimitry Andric 14880b57cec5SDimitry Andric if (!implementor.IsAllocated()) 14890b57cec5SDimitry Andric return ValueObjectListSP(); 14900b57cec5SDimitry Andric 1491*fe013be4SDimitry Andric PythonObject py_return(PyRefType::Owned, 1492*fe013be4SDimitry Andric SWIGBridge::LLDBSwigPython_GetRecognizedArguments( 1493*fe013be4SDimitry Andric implementor.get(), frame_sp)); 14940b57cec5SDimitry Andric 14950b57cec5SDimitry Andric // if it fails, print the error but otherwise go on 14960b57cec5SDimitry Andric if (PyErr_Occurred()) { 14970b57cec5SDimitry Andric PyErr_Print(); 14980b57cec5SDimitry Andric PyErr_Clear(); 14990b57cec5SDimitry Andric } 15000b57cec5SDimitry Andric if (py_return.get()) { 15010b57cec5SDimitry Andric PythonList result_list(PyRefType::Borrowed, py_return.get()); 15020b57cec5SDimitry Andric ValueObjectListSP result = ValueObjectListSP(new ValueObjectList()); 15030b57cec5SDimitry Andric for (size_t i = 0; i < result_list.GetSize(); i++) { 15040b57cec5SDimitry Andric PyObject *item = result_list.GetItemAtIndex(i).get(); 15050b57cec5SDimitry Andric lldb::SBValue *sb_value_ptr = 15060b57cec5SDimitry Andric (lldb::SBValue *)LLDBSWIGPython_CastPyObjectToSBValue(item); 1507*fe013be4SDimitry Andric auto valobj_sp = 1508*fe013be4SDimitry Andric SWIGBridge::LLDBSWIGPython_GetValueObjectSPFromSBValue(sb_value_ptr); 15090b57cec5SDimitry Andric if (valobj_sp) 15100b57cec5SDimitry Andric result->Append(valobj_sp); 15110b57cec5SDimitry Andric } 15120b57cec5SDimitry Andric return result; 15130b57cec5SDimitry Andric } 15140b57cec5SDimitry Andric return ValueObjectListSP(); 15150b57cec5SDimitry Andric } 15160b57cec5SDimitry Andric 1517*fe013be4SDimitry Andric ScriptedProcessInterfaceUP 1518*fe013be4SDimitry Andric ScriptInterpreterPythonImpl::CreateScriptedProcessInterface() { 1519*fe013be4SDimitry Andric return std::make_unique<ScriptedProcessPythonInterface>(*this); 1520*fe013be4SDimitry Andric } 1521*fe013be4SDimitry Andric 1522*fe013be4SDimitry Andric StructuredData::ObjectSP 1523*fe013be4SDimitry Andric ScriptInterpreterPythonImpl::CreateStructuredDataFromScriptObject( 1524*fe013be4SDimitry Andric ScriptObject obj) { 1525*fe013be4SDimitry Andric void *ptr = const_cast<void *>(obj.GetPointer()); 1526*fe013be4SDimitry Andric PythonObject py_obj(PyRefType::Borrowed, static_cast<PyObject *>(ptr)); 1527*fe013be4SDimitry Andric if (!py_obj.IsValid() || py_obj.IsNone()) 1528*fe013be4SDimitry Andric return {}; 1529*fe013be4SDimitry Andric Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock); 1530*fe013be4SDimitry Andric return py_obj.CreateStructuredObject(); 1531*fe013be4SDimitry Andric } 1532*fe013be4SDimitry Andric 15330b57cec5SDimitry Andric StructuredData::GenericSP 15340b57cec5SDimitry Andric ScriptInterpreterPythonImpl::OSPlugin_CreatePluginObject( 15350b57cec5SDimitry Andric const char *class_name, lldb::ProcessSP process_sp) { 15360b57cec5SDimitry Andric if (class_name == nullptr || class_name[0] == '\0') 15370b57cec5SDimitry Andric return StructuredData::GenericSP(); 15380b57cec5SDimitry Andric 15390b57cec5SDimitry Andric if (!process_sp) 15400b57cec5SDimitry Andric return StructuredData::GenericSP(); 15410b57cec5SDimitry Andric 154204eeddc0SDimitry Andric Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock); 1543*fe013be4SDimitry Andric PythonObject ret_val = SWIGBridge::LLDBSWIGPythonCreateOSPlugin( 15440b57cec5SDimitry Andric class_name, m_dictionary_name.c_str(), process_sp); 15450b57cec5SDimitry Andric 154604eeddc0SDimitry Andric return StructuredData::GenericSP( 154704eeddc0SDimitry Andric new StructuredPythonObject(std::move(ret_val))); 15480b57cec5SDimitry Andric } 15490b57cec5SDimitry Andric 15500b57cec5SDimitry Andric StructuredData::DictionarySP ScriptInterpreterPythonImpl::OSPlugin_RegisterInfo( 15510b57cec5SDimitry Andric StructuredData::ObjectSP os_plugin_object_sp) { 15520b57cec5SDimitry Andric Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock); 15530b57cec5SDimitry Andric 15540b57cec5SDimitry Andric if (!os_plugin_object_sp) 1555bdd1243dSDimitry Andric return {}; 15560b57cec5SDimitry Andric 15570b57cec5SDimitry Andric StructuredData::Generic *generic = os_plugin_object_sp->GetAsGeneric(); 15580b57cec5SDimitry Andric if (!generic) 1559bdd1243dSDimitry Andric return {}; 15600b57cec5SDimitry Andric 15610b57cec5SDimitry Andric PythonObject implementor(PyRefType::Borrowed, 15620b57cec5SDimitry Andric (PyObject *)generic->GetValue()); 15630b57cec5SDimitry Andric 15640b57cec5SDimitry Andric if (!implementor.IsAllocated()) 1565bdd1243dSDimitry Andric return {}; 15660b57cec5SDimitry Andric 1567bdd1243dSDimitry Andric llvm::Expected<PythonObject> expected_py_return = 1568bdd1243dSDimitry Andric implementor.CallMethod("get_register_info"); 15690b57cec5SDimitry Andric 1570bdd1243dSDimitry Andric if (!expected_py_return) { 1571bdd1243dSDimitry Andric llvm::consumeError(expected_py_return.takeError()); 1572bdd1243dSDimitry Andric return {}; 15730b57cec5SDimitry Andric } 15740b57cec5SDimitry Andric 1575bdd1243dSDimitry Andric PythonObject py_return = std::move(expected_py_return.get()); 15760b57cec5SDimitry Andric 15770b57cec5SDimitry Andric if (py_return.get()) { 15780b57cec5SDimitry Andric PythonDictionary result_dict(PyRefType::Borrowed, py_return.get()); 15790b57cec5SDimitry Andric return result_dict.CreateStructuredDictionary(); 15800b57cec5SDimitry Andric } 15810b57cec5SDimitry Andric return StructuredData::DictionarySP(); 15820b57cec5SDimitry Andric } 15830b57cec5SDimitry Andric 15840b57cec5SDimitry Andric StructuredData::ArraySP ScriptInterpreterPythonImpl::OSPlugin_ThreadsInfo( 15850b57cec5SDimitry Andric StructuredData::ObjectSP os_plugin_object_sp) { 15860b57cec5SDimitry Andric Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock); 15870b57cec5SDimitry Andric if (!os_plugin_object_sp) 1588bdd1243dSDimitry Andric return {}; 15890b57cec5SDimitry Andric 15900b57cec5SDimitry Andric StructuredData::Generic *generic = os_plugin_object_sp->GetAsGeneric(); 15910b57cec5SDimitry Andric if (!generic) 1592bdd1243dSDimitry Andric return {}; 15930b57cec5SDimitry Andric 15940b57cec5SDimitry Andric PythonObject implementor(PyRefType::Borrowed, 15950b57cec5SDimitry Andric (PyObject *)generic->GetValue()); 15960b57cec5SDimitry Andric 15970b57cec5SDimitry Andric if (!implementor.IsAllocated()) 1598bdd1243dSDimitry Andric return {}; 15990b57cec5SDimitry Andric 1600bdd1243dSDimitry Andric llvm::Expected<PythonObject> expected_py_return = 1601bdd1243dSDimitry Andric implementor.CallMethod("get_thread_info"); 16020b57cec5SDimitry Andric 1603bdd1243dSDimitry Andric if (!expected_py_return) { 1604bdd1243dSDimitry Andric llvm::consumeError(expected_py_return.takeError()); 1605bdd1243dSDimitry Andric return {}; 16060b57cec5SDimitry Andric } 16070b57cec5SDimitry Andric 1608bdd1243dSDimitry Andric PythonObject py_return = std::move(expected_py_return.get()); 16090b57cec5SDimitry Andric 16100b57cec5SDimitry Andric if (py_return.get()) { 16110b57cec5SDimitry Andric PythonList result_list(PyRefType::Borrowed, py_return.get()); 16120b57cec5SDimitry Andric return result_list.CreateStructuredArray(); 16130b57cec5SDimitry Andric } 16140b57cec5SDimitry Andric return StructuredData::ArraySP(); 16150b57cec5SDimitry Andric } 16160b57cec5SDimitry Andric 16170b57cec5SDimitry Andric StructuredData::StringSP 16180b57cec5SDimitry Andric ScriptInterpreterPythonImpl::OSPlugin_RegisterContextData( 16190b57cec5SDimitry Andric StructuredData::ObjectSP os_plugin_object_sp, lldb::tid_t tid) { 16200b57cec5SDimitry Andric Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock); 16210b57cec5SDimitry Andric 16220b57cec5SDimitry Andric if (!os_plugin_object_sp) 1623bdd1243dSDimitry Andric return {}; 16240b57cec5SDimitry Andric 16250b57cec5SDimitry Andric StructuredData::Generic *generic = os_plugin_object_sp->GetAsGeneric(); 16260b57cec5SDimitry Andric if (!generic) 1627bdd1243dSDimitry Andric return {}; 16280b57cec5SDimitry Andric PythonObject implementor(PyRefType::Borrowed, 16290b57cec5SDimitry Andric (PyObject *)generic->GetValue()); 16300b57cec5SDimitry Andric 16310b57cec5SDimitry Andric if (!implementor.IsAllocated()) 1632bdd1243dSDimitry Andric return {}; 16330b57cec5SDimitry Andric 1634bdd1243dSDimitry Andric llvm::Expected<PythonObject> expected_py_return = 1635bdd1243dSDimitry Andric implementor.CallMethod("get_register_data", tid); 16360b57cec5SDimitry Andric 1637bdd1243dSDimitry Andric if (!expected_py_return) { 1638bdd1243dSDimitry Andric llvm::consumeError(expected_py_return.takeError()); 1639bdd1243dSDimitry Andric return {}; 16400b57cec5SDimitry Andric } 16410b57cec5SDimitry Andric 1642bdd1243dSDimitry Andric PythonObject py_return = std::move(expected_py_return.get()); 16430b57cec5SDimitry Andric 16440b57cec5SDimitry Andric if (py_return.get()) { 16450b57cec5SDimitry Andric PythonBytes result(PyRefType::Borrowed, py_return.get()); 16460b57cec5SDimitry Andric return result.CreateStructuredString(); 16470b57cec5SDimitry Andric } 1648bdd1243dSDimitry Andric return {}; 16490b57cec5SDimitry Andric } 16500b57cec5SDimitry Andric 16510b57cec5SDimitry Andric StructuredData::DictionarySP ScriptInterpreterPythonImpl::OSPlugin_CreateThread( 16520b57cec5SDimitry Andric StructuredData::ObjectSP os_plugin_object_sp, lldb::tid_t tid, 16530b57cec5SDimitry Andric lldb::addr_t context) { 16540b57cec5SDimitry Andric Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock); 16550b57cec5SDimitry Andric 16560b57cec5SDimitry Andric if (!os_plugin_object_sp) 1657bdd1243dSDimitry Andric return {}; 16580b57cec5SDimitry Andric 16590b57cec5SDimitry Andric StructuredData::Generic *generic = os_plugin_object_sp->GetAsGeneric(); 16600b57cec5SDimitry Andric if (!generic) 1661bdd1243dSDimitry Andric return {}; 16620b57cec5SDimitry Andric 16630b57cec5SDimitry Andric PythonObject implementor(PyRefType::Borrowed, 16640b57cec5SDimitry Andric (PyObject *)generic->GetValue()); 16650b57cec5SDimitry Andric 16660b57cec5SDimitry Andric if (!implementor.IsAllocated()) 1667bdd1243dSDimitry Andric return {}; 16680b57cec5SDimitry Andric 1669bdd1243dSDimitry Andric llvm::Expected<PythonObject> expected_py_return = 1670bdd1243dSDimitry Andric implementor.CallMethod("create_thread", tid, context); 16710b57cec5SDimitry Andric 1672bdd1243dSDimitry Andric if (!expected_py_return) { 1673bdd1243dSDimitry Andric llvm::consumeError(expected_py_return.takeError()); 1674bdd1243dSDimitry Andric return {}; 16750b57cec5SDimitry Andric } 16760b57cec5SDimitry Andric 1677bdd1243dSDimitry Andric PythonObject py_return = std::move(expected_py_return.get()); 16780b57cec5SDimitry Andric 16790b57cec5SDimitry Andric if (py_return.get()) { 16800b57cec5SDimitry Andric PythonDictionary result_dict(PyRefType::Borrowed, py_return.get()); 16810b57cec5SDimitry Andric return result_dict.CreateStructuredDictionary(); 16820b57cec5SDimitry Andric } 16830b57cec5SDimitry Andric return StructuredData::DictionarySP(); 16840b57cec5SDimitry Andric } 16850b57cec5SDimitry Andric 16860b57cec5SDimitry Andric StructuredData::ObjectSP ScriptInterpreterPythonImpl::CreateScriptedThreadPlan( 16870eae32dcSDimitry Andric const char *class_name, const StructuredDataImpl &args_data, 1688480093f4SDimitry Andric std::string &error_str, lldb::ThreadPlanSP thread_plan_sp) { 16890b57cec5SDimitry Andric if (class_name == nullptr || class_name[0] == '\0') 16900b57cec5SDimitry Andric return StructuredData::ObjectSP(); 16910b57cec5SDimitry Andric 16920b57cec5SDimitry Andric if (!thread_plan_sp.get()) 16939dba64beSDimitry Andric return {}; 16940b57cec5SDimitry Andric 16950b57cec5SDimitry Andric Debugger &debugger = thread_plan_sp->GetTarget().GetDebugger(); 16960b57cec5SDimitry Andric ScriptInterpreterPythonImpl *python_interpreter = 1697e8d8bef9SDimitry Andric GetPythonInterpreter(debugger); 16980b57cec5SDimitry Andric 1699e8d8bef9SDimitry Andric if (!python_interpreter) 17009dba64beSDimitry Andric return {}; 17010b57cec5SDimitry Andric 17020b57cec5SDimitry Andric Locker py_lock(this, 17030b57cec5SDimitry Andric Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); 1704*fe013be4SDimitry Andric PythonObject ret_val = SWIGBridge::LLDBSwigPythonCreateScriptedThreadPlan( 170504eeddc0SDimitry Andric class_name, python_interpreter->m_dictionary_name.c_str(), args_data, 170604eeddc0SDimitry Andric error_str, thread_plan_sp); 17079dba64beSDimitry Andric if (!ret_val) 17089dba64beSDimitry Andric return {}; 17090b57cec5SDimitry Andric 171004eeddc0SDimitry Andric return StructuredData::ObjectSP( 171104eeddc0SDimitry Andric new StructuredPythonObject(std::move(ret_val))); 17120b57cec5SDimitry Andric } 17130b57cec5SDimitry Andric 17140b57cec5SDimitry Andric bool ScriptInterpreterPythonImpl::ScriptedThreadPlanExplainsStop( 17150b57cec5SDimitry Andric StructuredData::ObjectSP implementor_sp, Event *event, bool &script_error) { 17160b57cec5SDimitry Andric bool explains_stop = true; 17170b57cec5SDimitry Andric StructuredData::Generic *generic = nullptr; 17180b57cec5SDimitry Andric if (implementor_sp) 17190b57cec5SDimitry Andric generic = implementor_sp->GetAsGeneric(); 17200b57cec5SDimitry Andric if (generic) { 17210b57cec5SDimitry Andric Locker py_lock(this, 17220b57cec5SDimitry Andric Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); 1723*fe013be4SDimitry Andric explains_stop = SWIGBridge::LLDBSWIGPythonCallThreadPlan( 17240b57cec5SDimitry Andric generic->GetValue(), "explains_stop", event, script_error); 17250b57cec5SDimitry Andric if (script_error) 17260b57cec5SDimitry Andric return true; 17270b57cec5SDimitry Andric } 17280b57cec5SDimitry Andric return explains_stop; 17290b57cec5SDimitry Andric } 17300b57cec5SDimitry Andric 17310b57cec5SDimitry Andric bool ScriptInterpreterPythonImpl::ScriptedThreadPlanShouldStop( 17320b57cec5SDimitry Andric StructuredData::ObjectSP implementor_sp, Event *event, bool &script_error) { 17330b57cec5SDimitry Andric bool should_stop = true; 17340b57cec5SDimitry Andric StructuredData::Generic *generic = nullptr; 17350b57cec5SDimitry Andric if (implementor_sp) 17360b57cec5SDimitry Andric generic = implementor_sp->GetAsGeneric(); 17370b57cec5SDimitry Andric if (generic) { 17380b57cec5SDimitry Andric Locker py_lock(this, 17390b57cec5SDimitry Andric Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); 1740*fe013be4SDimitry Andric should_stop = SWIGBridge::LLDBSWIGPythonCallThreadPlan( 17410b57cec5SDimitry Andric generic->GetValue(), "should_stop", event, script_error); 17420b57cec5SDimitry Andric if (script_error) 17430b57cec5SDimitry Andric return true; 17440b57cec5SDimitry Andric } 17450b57cec5SDimitry Andric return should_stop; 17460b57cec5SDimitry Andric } 17470b57cec5SDimitry Andric 17480b57cec5SDimitry Andric bool ScriptInterpreterPythonImpl::ScriptedThreadPlanIsStale( 17490b57cec5SDimitry Andric StructuredData::ObjectSP implementor_sp, bool &script_error) { 17500b57cec5SDimitry Andric bool is_stale = true; 17510b57cec5SDimitry Andric StructuredData::Generic *generic = nullptr; 17520b57cec5SDimitry Andric if (implementor_sp) 17530b57cec5SDimitry Andric generic = implementor_sp->GetAsGeneric(); 17540b57cec5SDimitry Andric if (generic) { 17550b57cec5SDimitry Andric Locker py_lock(this, 17560b57cec5SDimitry Andric Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); 1757*fe013be4SDimitry Andric is_stale = SWIGBridge::LLDBSWIGPythonCallThreadPlan( 1758*fe013be4SDimitry Andric generic->GetValue(), "is_stale", (Event *)nullptr, script_error); 17590b57cec5SDimitry Andric if (script_error) 17600b57cec5SDimitry Andric return true; 17610b57cec5SDimitry Andric } 17620b57cec5SDimitry Andric return is_stale; 17630b57cec5SDimitry Andric } 17640b57cec5SDimitry Andric 17650b57cec5SDimitry Andric lldb::StateType ScriptInterpreterPythonImpl::ScriptedThreadPlanGetRunState( 17660b57cec5SDimitry Andric StructuredData::ObjectSP implementor_sp, bool &script_error) { 17670b57cec5SDimitry Andric bool should_step = false; 17680b57cec5SDimitry Andric StructuredData::Generic *generic = nullptr; 17690b57cec5SDimitry Andric if (implementor_sp) 17700b57cec5SDimitry Andric generic = implementor_sp->GetAsGeneric(); 17710b57cec5SDimitry Andric if (generic) { 17720b57cec5SDimitry Andric Locker py_lock(this, 17730b57cec5SDimitry Andric Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); 1774*fe013be4SDimitry Andric should_step = SWIGBridge::LLDBSWIGPythonCallThreadPlan( 1775*fe013be4SDimitry Andric generic->GetValue(), "should_step", (Event *)nullptr, script_error); 17760b57cec5SDimitry Andric if (script_error) 17770b57cec5SDimitry Andric should_step = true; 17780b57cec5SDimitry Andric } 17790b57cec5SDimitry Andric if (should_step) 17800b57cec5SDimitry Andric return lldb::eStateStepping; 17810b57cec5SDimitry Andric return lldb::eStateRunning; 17820b57cec5SDimitry Andric } 17830b57cec5SDimitry Andric 1784*fe013be4SDimitry Andric bool 1785*fe013be4SDimitry Andric ScriptInterpreterPythonImpl::ScriptedThreadPlanGetStopDescription( 1786*fe013be4SDimitry Andric StructuredData::ObjectSP implementor_sp, lldb_private::Stream *stream, 1787*fe013be4SDimitry Andric bool &script_error) { 1788*fe013be4SDimitry Andric StructuredData::Generic *generic = nullptr; 1789*fe013be4SDimitry Andric if (implementor_sp) 1790*fe013be4SDimitry Andric generic = implementor_sp->GetAsGeneric(); 1791*fe013be4SDimitry Andric if (!generic) { 1792*fe013be4SDimitry Andric script_error = true; 1793*fe013be4SDimitry Andric return false; 1794*fe013be4SDimitry Andric } 1795*fe013be4SDimitry Andric Locker py_lock(this, 1796*fe013be4SDimitry Andric Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); 1797*fe013be4SDimitry Andric return SWIGBridge::LLDBSWIGPythonCallThreadPlan( 1798*fe013be4SDimitry Andric generic->GetValue(), "stop_description", stream, script_error); 1799*fe013be4SDimitry Andric } 1800*fe013be4SDimitry Andric 1801*fe013be4SDimitry Andric 18020b57cec5SDimitry Andric StructuredData::GenericSP 18030b57cec5SDimitry Andric ScriptInterpreterPythonImpl::CreateScriptedBreakpointResolver( 18040eae32dcSDimitry Andric const char *class_name, const StructuredDataImpl &args_data, 18050b57cec5SDimitry Andric lldb::BreakpointSP &bkpt_sp) { 18060b57cec5SDimitry Andric 18070b57cec5SDimitry Andric if (class_name == nullptr || class_name[0] == '\0') 18080b57cec5SDimitry Andric return StructuredData::GenericSP(); 18090b57cec5SDimitry Andric 18100b57cec5SDimitry Andric if (!bkpt_sp.get()) 18110b57cec5SDimitry Andric return StructuredData::GenericSP(); 18120b57cec5SDimitry Andric 18130b57cec5SDimitry Andric Debugger &debugger = bkpt_sp->GetTarget().GetDebugger(); 18140b57cec5SDimitry Andric ScriptInterpreterPythonImpl *python_interpreter = 1815e8d8bef9SDimitry Andric GetPythonInterpreter(debugger); 18160b57cec5SDimitry Andric 1817e8d8bef9SDimitry Andric if (!python_interpreter) 18180b57cec5SDimitry Andric return StructuredData::GenericSP(); 18190b57cec5SDimitry Andric 18200b57cec5SDimitry Andric Locker py_lock(this, 18210b57cec5SDimitry Andric Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); 18220b57cec5SDimitry Andric 1823*fe013be4SDimitry Andric PythonObject ret_val = 1824*fe013be4SDimitry Andric SWIGBridge::LLDBSwigPythonCreateScriptedBreakpointResolver( 18250b57cec5SDimitry Andric class_name, python_interpreter->m_dictionary_name.c_str(), args_data, 18260b57cec5SDimitry Andric bkpt_sp); 18270b57cec5SDimitry Andric 182804eeddc0SDimitry Andric return StructuredData::GenericSP( 182904eeddc0SDimitry Andric new StructuredPythonObject(std::move(ret_val))); 18300b57cec5SDimitry Andric } 18310b57cec5SDimitry Andric 18320b57cec5SDimitry Andric bool ScriptInterpreterPythonImpl::ScriptedBreakpointResolverSearchCallback( 18330b57cec5SDimitry Andric StructuredData::GenericSP implementor_sp, SymbolContext *sym_ctx) { 18340b57cec5SDimitry Andric bool should_continue = false; 18350b57cec5SDimitry Andric 18360b57cec5SDimitry Andric if (implementor_sp) { 18370b57cec5SDimitry Andric Locker py_lock(this, 18380b57cec5SDimitry Andric Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); 1839*fe013be4SDimitry Andric should_continue = SWIGBridge::LLDBSwigPythonCallBreakpointResolver( 18400b57cec5SDimitry Andric implementor_sp->GetValue(), "__callback__", sym_ctx); 18410b57cec5SDimitry Andric if (PyErr_Occurred()) { 18420b57cec5SDimitry Andric PyErr_Print(); 18430b57cec5SDimitry Andric PyErr_Clear(); 18440b57cec5SDimitry Andric } 18450b57cec5SDimitry Andric } 18460b57cec5SDimitry Andric return should_continue; 18470b57cec5SDimitry Andric } 18480b57cec5SDimitry Andric 18490b57cec5SDimitry Andric lldb::SearchDepth 18500b57cec5SDimitry Andric ScriptInterpreterPythonImpl::ScriptedBreakpointResolverSearchDepth( 18510b57cec5SDimitry Andric StructuredData::GenericSP implementor_sp) { 18520b57cec5SDimitry Andric int depth_as_int = lldb::eSearchDepthModule; 18530b57cec5SDimitry Andric if (implementor_sp) { 18540b57cec5SDimitry Andric Locker py_lock(this, 18550b57cec5SDimitry Andric Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); 1856*fe013be4SDimitry Andric depth_as_int = SWIGBridge::LLDBSwigPythonCallBreakpointResolver( 18570b57cec5SDimitry Andric implementor_sp->GetValue(), "__get_depth__", nullptr); 18580b57cec5SDimitry Andric if (PyErr_Occurred()) { 18590b57cec5SDimitry Andric PyErr_Print(); 18600b57cec5SDimitry Andric PyErr_Clear(); 18610b57cec5SDimitry Andric } 18620b57cec5SDimitry Andric } 18630b57cec5SDimitry Andric if (depth_as_int == lldb::eSearchDepthInvalid) 18640b57cec5SDimitry Andric return lldb::eSearchDepthModule; 18650b57cec5SDimitry Andric 18660b57cec5SDimitry Andric if (depth_as_int <= lldb::kLastSearchDepthKind) 18670b57cec5SDimitry Andric return (lldb::SearchDepth)depth_as_int; 18680b57cec5SDimitry Andric return lldb::eSearchDepthModule; 18690b57cec5SDimitry Andric } 18700b57cec5SDimitry Andric 1871e8d8bef9SDimitry Andric StructuredData::GenericSP ScriptInterpreterPythonImpl::CreateScriptedStopHook( 18720eae32dcSDimitry Andric TargetSP target_sp, const char *class_name, 18730eae32dcSDimitry Andric const StructuredDataImpl &args_data, Status &error) { 1874e8d8bef9SDimitry Andric 1875e8d8bef9SDimitry Andric if (!target_sp) { 1876e8d8bef9SDimitry Andric error.SetErrorString("No target for scripted stop-hook."); 1877e8d8bef9SDimitry Andric return StructuredData::GenericSP(); 1878e8d8bef9SDimitry Andric } 1879e8d8bef9SDimitry Andric 1880e8d8bef9SDimitry Andric if (class_name == nullptr || class_name[0] == '\0') { 1881e8d8bef9SDimitry Andric error.SetErrorString("No class name for scripted stop-hook."); 1882e8d8bef9SDimitry Andric return StructuredData::GenericSP(); 1883e8d8bef9SDimitry Andric } 1884e8d8bef9SDimitry Andric 1885e8d8bef9SDimitry Andric ScriptInterpreterPythonImpl *python_interpreter = 1886e8d8bef9SDimitry Andric GetPythonInterpreter(m_debugger); 1887e8d8bef9SDimitry Andric 1888e8d8bef9SDimitry Andric if (!python_interpreter) { 1889e8d8bef9SDimitry Andric error.SetErrorString("No script interpreter for scripted stop-hook."); 1890e8d8bef9SDimitry Andric return StructuredData::GenericSP(); 1891e8d8bef9SDimitry Andric } 1892e8d8bef9SDimitry Andric 1893e8d8bef9SDimitry Andric Locker py_lock(this, 1894e8d8bef9SDimitry Andric Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); 1895e8d8bef9SDimitry Andric 1896*fe013be4SDimitry Andric PythonObject ret_val = SWIGBridge::LLDBSwigPythonCreateScriptedStopHook( 1897e8d8bef9SDimitry Andric target_sp, class_name, python_interpreter->m_dictionary_name.c_str(), 1898e8d8bef9SDimitry Andric args_data, error); 1899e8d8bef9SDimitry Andric 190004eeddc0SDimitry Andric return StructuredData::GenericSP( 190104eeddc0SDimitry Andric new StructuredPythonObject(std::move(ret_val))); 1902e8d8bef9SDimitry Andric } 1903e8d8bef9SDimitry Andric 1904e8d8bef9SDimitry Andric bool ScriptInterpreterPythonImpl::ScriptedStopHookHandleStop( 1905e8d8bef9SDimitry Andric StructuredData::GenericSP implementor_sp, ExecutionContext &exc_ctx, 1906e8d8bef9SDimitry Andric lldb::StreamSP stream_sp) { 1907e8d8bef9SDimitry Andric assert(implementor_sp && 1908e8d8bef9SDimitry Andric "can't call a stop hook with an invalid implementor"); 1909e8d8bef9SDimitry Andric assert(stream_sp && "can't call a stop hook with an invalid stream"); 1910e8d8bef9SDimitry Andric 1911e8d8bef9SDimitry Andric Locker py_lock(this, 1912e8d8bef9SDimitry Andric Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); 1913e8d8bef9SDimitry Andric 1914e8d8bef9SDimitry Andric lldb::ExecutionContextRefSP exc_ctx_ref_sp(new ExecutionContextRef(exc_ctx)); 1915e8d8bef9SDimitry Andric 1916*fe013be4SDimitry Andric bool ret_val = SWIGBridge::LLDBSwigPythonStopHookCallHandleStop( 1917e8d8bef9SDimitry Andric implementor_sp->GetValue(), exc_ctx_ref_sp, stream_sp); 1918e8d8bef9SDimitry Andric return ret_val; 1919e8d8bef9SDimitry Andric } 1920e8d8bef9SDimitry Andric 19210b57cec5SDimitry Andric StructuredData::ObjectSP 19220b57cec5SDimitry Andric ScriptInterpreterPythonImpl::LoadPluginModule(const FileSpec &file_spec, 19230b57cec5SDimitry Andric lldb_private::Status &error) { 19240b57cec5SDimitry Andric if (!FileSystem::Instance().Exists(file_spec)) { 19250b57cec5SDimitry Andric error.SetErrorString("no such file"); 19260b57cec5SDimitry Andric return StructuredData::ObjectSP(); 19270b57cec5SDimitry Andric } 19280b57cec5SDimitry Andric 19290b57cec5SDimitry Andric StructuredData::ObjectSP module_sp; 19300b57cec5SDimitry Andric 1931fe6060f1SDimitry Andric LoadScriptOptions load_script_options = 1932fe6060f1SDimitry Andric LoadScriptOptions().SetInitSession(true).SetSilent(false); 1933fe6060f1SDimitry Andric if (LoadScriptingModule(file_spec.GetPath().c_str(), load_script_options, 1934fe6060f1SDimitry Andric error, &module_sp)) 19350b57cec5SDimitry Andric return module_sp; 19360b57cec5SDimitry Andric 19370b57cec5SDimitry Andric return StructuredData::ObjectSP(); 19380b57cec5SDimitry Andric } 19390b57cec5SDimitry Andric 19400b57cec5SDimitry Andric StructuredData::DictionarySP ScriptInterpreterPythonImpl::GetDynamicSettings( 19410b57cec5SDimitry Andric StructuredData::ObjectSP plugin_module_sp, Target *target, 19420b57cec5SDimitry Andric const char *setting_name, lldb_private::Status &error) { 19430b57cec5SDimitry Andric if (!plugin_module_sp || !target || !setting_name || !setting_name[0]) 19440b57cec5SDimitry Andric return StructuredData::DictionarySP(); 19450b57cec5SDimitry Andric StructuredData::Generic *generic = plugin_module_sp->GetAsGeneric(); 19460b57cec5SDimitry Andric if (!generic) 19470b57cec5SDimitry Andric return StructuredData::DictionarySP(); 19480b57cec5SDimitry Andric 19490b57cec5SDimitry Andric Locker py_lock(this, 19500b57cec5SDimitry Andric Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); 19510b57cec5SDimitry Andric TargetSP target_sp(target->shared_from_this()); 19520b57cec5SDimitry Andric 1953*fe013be4SDimitry Andric auto setting = (PyObject *)SWIGBridge::LLDBSWIGPython_GetDynamicSetting( 19549dba64beSDimitry Andric generic->GetValue(), setting_name, target_sp); 19559dba64beSDimitry Andric 19569dba64beSDimitry Andric if (!setting) 19579dba64beSDimitry Andric return StructuredData::DictionarySP(); 19589dba64beSDimitry Andric 19599dba64beSDimitry Andric PythonDictionary py_dict = 19609dba64beSDimitry Andric unwrapIgnoringErrors(As<PythonDictionary>(Take<PythonObject>(setting))); 19619dba64beSDimitry Andric 19629dba64beSDimitry Andric if (!py_dict) 19639dba64beSDimitry Andric return StructuredData::DictionarySP(); 19649dba64beSDimitry Andric 19650b57cec5SDimitry Andric return py_dict.CreateStructuredDictionary(); 19660b57cec5SDimitry Andric } 19670b57cec5SDimitry Andric 19680b57cec5SDimitry Andric StructuredData::ObjectSP 19690b57cec5SDimitry Andric ScriptInterpreterPythonImpl::CreateSyntheticScriptedProvider( 19700b57cec5SDimitry Andric const char *class_name, lldb::ValueObjectSP valobj) { 19710b57cec5SDimitry Andric if (class_name == nullptr || class_name[0] == '\0') 19720b57cec5SDimitry Andric return StructuredData::ObjectSP(); 19730b57cec5SDimitry Andric 19740b57cec5SDimitry Andric if (!valobj.get()) 19750b57cec5SDimitry Andric return StructuredData::ObjectSP(); 19760b57cec5SDimitry Andric 19770b57cec5SDimitry Andric ExecutionContext exe_ctx(valobj->GetExecutionContextRef()); 19780b57cec5SDimitry Andric Target *target = exe_ctx.GetTargetPtr(); 19790b57cec5SDimitry Andric 19800b57cec5SDimitry Andric if (!target) 19810b57cec5SDimitry Andric return StructuredData::ObjectSP(); 19820b57cec5SDimitry Andric 19830b57cec5SDimitry Andric Debugger &debugger = target->GetDebugger(); 19840b57cec5SDimitry Andric ScriptInterpreterPythonImpl *python_interpreter = 1985e8d8bef9SDimitry Andric GetPythonInterpreter(debugger); 19860b57cec5SDimitry Andric 1987e8d8bef9SDimitry Andric if (!python_interpreter) 19880b57cec5SDimitry Andric return StructuredData::ObjectSP(); 19890b57cec5SDimitry Andric 19900b57cec5SDimitry Andric Locker py_lock(this, 19910b57cec5SDimitry Andric Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); 1992*fe013be4SDimitry Andric PythonObject ret_val = SWIGBridge::LLDBSwigPythonCreateSyntheticProvider( 19930b57cec5SDimitry Andric class_name, python_interpreter->m_dictionary_name.c_str(), valobj); 19940b57cec5SDimitry Andric 199504eeddc0SDimitry Andric return StructuredData::ObjectSP( 199604eeddc0SDimitry Andric new StructuredPythonObject(std::move(ret_val))); 19970b57cec5SDimitry Andric } 19980b57cec5SDimitry Andric 19990b57cec5SDimitry Andric StructuredData::GenericSP 20000b57cec5SDimitry Andric ScriptInterpreterPythonImpl::CreateScriptCommandObject(const char *class_name) { 20010b57cec5SDimitry Andric DebuggerSP debugger_sp(m_debugger.shared_from_this()); 20020b57cec5SDimitry Andric 20030b57cec5SDimitry Andric if (class_name == nullptr || class_name[0] == '\0') 20040b57cec5SDimitry Andric return StructuredData::GenericSP(); 20050b57cec5SDimitry Andric 20060b57cec5SDimitry Andric if (!debugger_sp.get()) 20070b57cec5SDimitry Andric return StructuredData::GenericSP(); 20080b57cec5SDimitry Andric 20090b57cec5SDimitry Andric Locker py_lock(this, 20100b57cec5SDimitry Andric Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); 2011*fe013be4SDimitry Andric PythonObject ret_val = SWIGBridge::LLDBSwigPythonCreateCommandObject( 20120b57cec5SDimitry Andric class_name, m_dictionary_name.c_str(), debugger_sp); 20130b57cec5SDimitry Andric 2014*fe013be4SDimitry Andric if (ret_val.IsValid()) 201504eeddc0SDimitry Andric return StructuredData::GenericSP( 201604eeddc0SDimitry Andric new StructuredPythonObject(std::move(ret_val))); 2017*fe013be4SDimitry Andric else 2018*fe013be4SDimitry Andric return {}; 20190b57cec5SDimitry Andric } 20200b57cec5SDimitry Andric 20210b57cec5SDimitry Andric bool ScriptInterpreterPythonImpl::GenerateTypeScriptFunction( 20220b57cec5SDimitry Andric const char *oneliner, std::string &output, const void *name_token) { 20230b57cec5SDimitry Andric StringList input; 20240b57cec5SDimitry Andric input.SplitIntoLines(oneliner, strlen(oneliner)); 20250b57cec5SDimitry Andric return GenerateTypeScriptFunction(input, output, name_token); 20260b57cec5SDimitry Andric } 20270b57cec5SDimitry Andric 20280b57cec5SDimitry Andric bool ScriptInterpreterPythonImpl::GenerateTypeSynthClass( 20290b57cec5SDimitry Andric const char *oneliner, std::string &output, const void *name_token) { 20300b57cec5SDimitry Andric StringList input; 20310b57cec5SDimitry Andric input.SplitIntoLines(oneliner, strlen(oneliner)); 20320b57cec5SDimitry Andric return GenerateTypeSynthClass(input, output, name_token); 20330b57cec5SDimitry Andric } 20340b57cec5SDimitry Andric 20350b57cec5SDimitry Andric Status ScriptInterpreterPythonImpl::GenerateBreakpointCommandCallbackData( 2036*fe013be4SDimitry Andric StringList &user_input, std::string &output, bool has_extra_args, 2037*fe013be4SDimitry Andric bool is_callback) { 20380b57cec5SDimitry Andric static uint32_t num_created_functions = 0; 20390b57cec5SDimitry Andric user_input.RemoveBlankLines(); 20400b57cec5SDimitry Andric StreamString sstr; 20410b57cec5SDimitry Andric Status error; 20420b57cec5SDimitry Andric if (user_input.GetSize() == 0) { 20430b57cec5SDimitry Andric error.SetErrorString("No input data."); 20440b57cec5SDimitry Andric return error; 20450b57cec5SDimitry Andric } 20460b57cec5SDimitry Andric 20470b57cec5SDimitry Andric std::string auto_generated_function_name(GenerateUniqueName( 20480b57cec5SDimitry Andric "lldb_autogen_python_bp_callback_func_", num_created_functions)); 2049480093f4SDimitry Andric if (has_extra_args) 2050480093f4SDimitry Andric sstr.Printf("def %s (frame, bp_loc, extra_args, internal_dict):", 2051480093f4SDimitry Andric auto_generated_function_name.c_str()); 2052480093f4SDimitry Andric else 20530b57cec5SDimitry Andric sstr.Printf("def %s (frame, bp_loc, internal_dict):", 20540b57cec5SDimitry Andric auto_generated_function_name.c_str()); 20550b57cec5SDimitry Andric 2056*fe013be4SDimitry Andric error = GenerateFunction(sstr.GetData(), user_input, is_callback); 20570b57cec5SDimitry Andric if (!error.Success()) 20580b57cec5SDimitry Andric return error; 20590b57cec5SDimitry Andric 20600b57cec5SDimitry Andric // Store the name of the auto-generated function to be called. 20610b57cec5SDimitry Andric output.assign(auto_generated_function_name); 20620b57cec5SDimitry Andric return error; 20630b57cec5SDimitry Andric } 20640b57cec5SDimitry Andric 20650b57cec5SDimitry Andric bool ScriptInterpreterPythonImpl::GenerateWatchpointCommandCallbackData( 2066*fe013be4SDimitry Andric StringList &user_input, std::string &output, bool is_callback) { 20670b57cec5SDimitry Andric static uint32_t num_created_functions = 0; 20680b57cec5SDimitry Andric user_input.RemoveBlankLines(); 20690b57cec5SDimitry Andric StreamString sstr; 20700b57cec5SDimitry Andric 20710b57cec5SDimitry Andric if (user_input.GetSize() == 0) 20720b57cec5SDimitry Andric return false; 20730b57cec5SDimitry Andric 20740b57cec5SDimitry Andric std::string auto_generated_function_name(GenerateUniqueName( 20750b57cec5SDimitry Andric "lldb_autogen_python_wp_callback_func_", num_created_functions)); 20760b57cec5SDimitry Andric sstr.Printf("def %s (frame, wp, internal_dict):", 20770b57cec5SDimitry Andric auto_generated_function_name.c_str()); 20780b57cec5SDimitry Andric 2079*fe013be4SDimitry Andric if (!GenerateFunction(sstr.GetData(), user_input, is_callback).Success()) 20800b57cec5SDimitry Andric return false; 20810b57cec5SDimitry Andric 20820b57cec5SDimitry Andric // Store the name of the auto-generated function to be called. 20830b57cec5SDimitry Andric output.assign(auto_generated_function_name); 20840b57cec5SDimitry Andric return true; 20850b57cec5SDimitry Andric } 20860b57cec5SDimitry Andric 20870b57cec5SDimitry Andric bool ScriptInterpreterPythonImpl::GetScriptedSummary( 20880b57cec5SDimitry Andric const char *python_function_name, lldb::ValueObjectSP valobj, 20890b57cec5SDimitry Andric StructuredData::ObjectSP &callee_wrapper_sp, 20900b57cec5SDimitry Andric const TypeSummaryOptions &options, std::string &retval) { 20910b57cec5SDimitry Andric 2092e8d8bef9SDimitry Andric LLDB_SCOPED_TIMER(); 20930b57cec5SDimitry Andric 20940b57cec5SDimitry Andric if (!valobj.get()) { 20950b57cec5SDimitry Andric retval.assign("<no object>"); 20960b57cec5SDimitry Andric return false; 20970b57cec5SDimitry Andric } 20980b57cec5SDimitry Andric 20990b57cec5SDimitry Andric void *old_callee = nullptr; 21000b57cec5SDimitry Andric StructuredData::Generic *generic = nullptr; 21010b57cec5SDimitry Andric if (callee_wrapper_sp) { 21020b57cec5SDimitry Andric generic = callee_wrapper_sp->GetAsGeneric(); 21030b57cec5SDimitry Andric if (generic) 21040b57cec5SDimitry Andric old_callee = generic->GetValue(); 21050b57cec5SDimitry Andric } 21060b57cec5SDimitry Andric void *new_callee = old_callee; 21070b57cec5SDimitry Andric 21080b57cec5SDimitry Andric bool ret_val; 21090b57cec5SDimitry Andric if (python_function_name && *python_function_name) { 21100b57cec5SDimitry Andric { 21110b57cec5SDimitry Andric Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | 21120b57cec5SDimitry Andric Locker::NoSTDIN); 21130b57cec5SDimitry Andric { 21140b57cec5SDimitry Andric TypeSummaryOptionsSP options_sp(new TypeSummaryOptions(options)); 21150b57cec5SDimitry Andric 21160b57cec5SDimitry Andric static Timer::Category func_cat("LLDBSwigPythonCallTypeScript"); 21170b57cec5SDimitry Andric Timer scoped_timer(func_cat, "LLDBSwigPythonCallTypeScript"); 2118*fe013be4SDimitry Andric ret_val = SWIGBridge::LLDBSwigPythonCallTypeScript( 21190b57cec5SDimitry Andric python_function_name, GetSessionDictionary().get(), valobj, 21200b57cec5SDimitry Andric &new_callee, options_sp, retval); 21210b57cec5SDimitry Andric } 21220b57cec5SDimitry Andric } 21230b57cec5SDimitry Andric } else { 21240b57cec5SDimitry Andric retval.assign("<no function name>"); 21250b57cec5SDimitry Andric return false; 21260b57cec5SDimitry Andric } 21270b57cec5SDimitry Andric 212804eeddc0SDimitry Andric if (new_callee && old_callee != new_callee) { 212904eeddc0SDimitry Andric Locker py_lock(this, 213004eeddc0SDimitry Andric Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); 213104eeddc0SDimitry Andric callee_wrapper_sp = std::make_shared<StructuredPythonObject>( 213204eeddc0SDimitry Andric PythonObject(PyRefType::Borrowed, static_cast<PyObject *>(new_callee))); 213304eeddc0SDimitry Andric } 21340b57cec5SDimitry Andric 21350b57cec5SDimitry Andric return ret_val; 21360b57cec5SDimitry Andric } 21370b57cec5SDimitry Andric 2138bdd1243dSDimitry Andric bool ScriptInterpreterPythonImpl::FormatterCallbackFunction( 2139bdd1243dSDimitry Andric const char *python_function_name, TypeImplSP type_impl_sp) { 2140bdd1243dSDimitry Andric Locker py_lock(this, 2141bdd1243dSDimitry Andric Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); 2142*fe013be4SDimitry Andric return SWIGBridge::LLDBSwigPythonFormatterCallbackFunction( 2143bdd1243dSDimitry Andric python_function_name, m_dictionary_name.c_str(), type_impl_sp); 2144bdd1243dSDimitry Andric } 2145bdd1243dSDimitry Andric 21460b57cec5SDimitry Andric bool ScriptInterpreterPythonImpl::BreakpointCallbackFunction( 21470b57cec5SDimitry Andric void *baton, StoppointCallbackContext *context, user_id_t break_id, 21480b57cec5SDimitry Andric user_id_t break_loc_id) { 21490b57cec5SDimitry Andric CommandDataPython *bp_option_data = (CommandDataPython *)baton; 21500b57cec5SDimitry Andric const char *python_function_name = bp_option_data->script_source.c_str(); 21510b57cec5SDimitry Andric 21520b57cec5SDimitry Andric if (!context) 21530b57cec5SDimitry Andric return true; 21540b57cec5SDimitry Andric 21550b57cec5SDimitry Andric ExecutionContext exe_ctx(context->exe_ctx_ref); 21560b57cec5SDimitry Andric Target *target = exe_ctx.GetTargetPtr(); 21570b57cec5SDimitry Andric 21580b57cec5SDimitry Andric if (!target) 21590b57cec5SDimitry Andric return true; 21600b57cec5SDimitry Andric 21610b57cec5SDimitry Andric Debugger &debugger = target->GetDebugger(); 21620b57cec5SDimitry Andric ScriptInterpreterPythonImpl *python_interpreter = 2163e8d8bef9SDimitry Andric GetPythonInterpreter(debugger); 21640b57cec5SDimitry Andric 2165e8d8bef9SDimitry Andric if (!python_interpreter) 21660b57cec5SDimitry Andric return true; 21670b57cec5SDimitry Andric 21680b57cec5SDimitry Andric if (python_function_name && python_function_name[0]) { 21690b57cec5SDimitry Andric const StackFrameSP stop_frame_sp(exe_ctx.GetFrameSP()); 21700b57cec5SDimitry Andric BreakpointSP breakpoint_sp = target->GetBreakpointByID(break_id); 21710b57cec5SDimitry Andric if (breakpoint_sp) { 21720b57cec5SDimitry Andric const BreakpointLocationSP bp_loc_sp( 21730b57cec5SDimitry Andric breakpoint_sp->FindLocationByID(break_loc_id)); 21740b57cec5SDimitry Andric 21750b57cec5SDimitry Andric if (stop_frame_sp && bp_loc_sp) { 21760b57cec5SDimitry Andric bool ret_val = true; 21770b57cec5SDimitry Andric { 21780b57cec5SDimitry Andric Locker py_lock(python_interpreter, Locker::AcquireLock | 21790b57cec5SDimitry Andric Locker::InitSession | 21800b57cec5SDimitry Andric Locker::NoSTDIN); 2181480093f4SDimitry Andric Expected<bool> maybe_ret_val = 2182*fe013be4SDimitry Andric SWIGBridge::LLDBSwigPythonBreakpointCallbackFunction( 21830b57cec5SDimitry Andric python_function_name, 21840b57cec5SDimitry Andric python_interpreter->m_dictionary_name.c_str(), stop_frame_sp, 21850eae32dcSDimitry Andric bp_loc_sp, bp_option_data->m_extra_args); 2186480093f4SDimitry Andric 2187480093f4SDimitry Andric if (!maybe_ret_val) { 2188480093f4SDimitry Andric 2189480093f4SDimitry Andric llvm::handleAllErrors( 2190480093f4SDimitry Andric maybe_ret_val.takeError(), 2191480093f4SDimitry Andric [&](PythonException &E) { 2192480093f4SDimitry Andric debugger.GetErrorStream() << E.ReadBacktrace(); 2193480093f4SDimitry Andric }, 2194480093f4SDimitry Andric [&](const llvm::ErrorInfoBase &E) { 2195480093f4SDimitry Andric debugger.GetErrorStream() << E.message(); 2196480093f4SDimitry Andric }); 2197480093f4SDimitry Andric 2198480093f4SDimitry Andric } else { 2199480093f4SDimitry Andric ret_val = maybe_ret_val.get(); 2200480093f4SDimitry Andric } 22010b57cec5SDimitry Andric } 22020b57cec5SDimitry Andric return ret_val; 22030b57cec5SDimitry Andric } 22040b57cec5SDimitry Andric } 22050b57cec5SDimitry Andric } 22060b57cec5SDimitry Andric // We currently always true so we stop in case anything goes wrong when 22070b57cec5SDimitry Andric // trying to call the script function 22080b57cec5SDimitry Andric return true; 22090b57cec5SDimitry Andric } 22100b57cec5SDimitry Andric 22110b57cec5SDimitry Andric bool ScriptInterpreterPythonImpl::WatchpointCallbackFunction( 22120b57cec5SDimitry Andric void *baton, StoppointCallbackContext *context, user_id_t watch_id) { 22130b57cec5SDimitry Andric WatchpointOptions::CommandData *wp_option_data = 22140b57cec5SDimitry Andric (WatchpointOptions::CommandData *)baton; 22150b57cec5SDimitry Andric const char *python_function_name = wp_option_data->script_source.c_str(); 22160b57cec5SDimitry Andric 22170b57cec5SDimitry Andric if (!context) 22180b57cec5SDimitry Andric return true; 22190b57cec5SDimitry Andric 22200b57cec5SDimitry Andric ExecutionContext exe_ctx(context->exe_ctx_ref); 22210b57cec5SDimitry Andric Target *target = exe_ctx.GetTargetPtr(); 22220b57cec5SDimitry Andric 22230b57cec5SDimitry Andric if (!target) 22240b57cec5SDimitry Andric return true; 22250b57cec5SDimitry Andric 22260b57cec5SDimitry Andric Debugger &debugger = target->GetDebugger(); 22270b57cec5SDimitry Andric ScriptInterpreterPythonImpl *python_interpreter = 2228e8d8bef9SDimitry Andric GetPythonInterpreter(debugger); 22290b57cec5SDimitry Andric 2230e8d8bef9SDimitry Andric if (!python_interpreter) 22310b57cec5SDimitry Andric return true; 22320b57cec5SDimitry Andric 22330b57cec5SDimitry Andric if (python_function_name && python_function_name[0]) { 22340b57cec5SDimitry Andric const StackFrameSP stop_frame_sp(exe_ctx.GetFrameSP()); 22350b57cec5SDimitry Andric WatchpointSP wp_sp = target->GetWatchpointList().FindByID(watch_id); 22360b57cec5SDimitry Andric if (wp_sp) { 22370b57cec5SDimitry Andric if (stop_frame_sp && wp_sp) { 22380b57cec5SDimitry Andric bool ret_val = true; 22390b57cec5SDimitry Andric { 22400b57cec5SDimitry Andric Locker py_lock(python_interpreter, Locker::AcquireLock | 22410b57cec5SDimitry Andric Locker::InitSession | 22420b57cec5SDimitry Andric Locker::NoSTDIN); 2243*fe013be4SDimitry Andric ret_val = SWIGBridge::LLDBSwigPythonWatchpointCallbackFunction( 22440b57cec5SDimitry Andric python_function_name, 22450b57cec5SDimitry Andric python_interpreter->m_dictionary_name.c_str(), stop_frame_sp, 22460b57cec5SDimitry Andric wp_sp); 22470b57cec5SDimitry Andric } 22480b57cec5SDimitry Andric return ret_val; 22490b57cec5SDimitry Andric } 22500b57cec5SDimitry Andric } 22510b57cec5SDimitry Andric } 22520b57cec5SDimitry Andric // We currently always true so we stop in case anything goes wrong when 22530b57cec5SDimitry Andric // trying to call the script function 22540b57cec5SDimitry Andric return true; 22550b57cec5SDimitry Andric } 22560b57cec5SDimitry Andric 22570b57cec5SDimitry Andric size_t ScriptInterpreterPythonImpl::CalculateNumChildren( 22580b57cec5SDimitry Andric const StructuredData::ObjectSP &implementor_sp, uint32_t max) { 22590b57cec5SDimitry Andric if (!implementor_sp) 22600b57cec5SDimitry Andric return 0; 22610b57cec5SDimitry Andric StructuredData::Generic *generic = implementor_sp->GetAsGeneric(); 22620b57cec5SDimitry Andric if (!generic) 22630b57cec5SDimitry Andric return 0; 22644824e7fdSDimitry Andric auto *implementor = static_cast<PyObject *>(generic->GetValue()); 22650b57cec5SDimitry Andric if (!implementor) 22660b57cec5SDimitry Andric return 0; 22670b57cec5SDimitry Andric 22680b57cec5SDimitry Andric size_t ret_val = 0; 22690b57cec5SDimitry Andric 22700b57cec5SDimitry Andric { 22710b57cec5SDimitry Andric Locker py_lock(this, 22720b57cec5SDimitry Andric Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); 2273*fe013be4SDimitry Andric ret_val = SWIGBridge::LLDBSwigPython_CalculateNumChildren(implementor, max); 22740b57cec5SDimitry Andric } 22750b57cec5SDimitry Andric 22760b57cec5SDimitry Andric return ret_val; 22770b57cec5SDimitry Andric } 22780b57cec5SDimitry Andric 22790b57cec5SDimitry Andric lldb::ValueObjectSP ScriptInterpreterPythonImpl::GetChildAtIndex( 22800b57cec5SDimitry Andric const StructuredData::ObjectSP &implementor_sp, uint32_t idx) { 22810b57cec5SDimitry Andric if (!implementor_sp) 22820b57cec5SDimitry Andric return lldb::ValueObjectSP(); 22830b57cec5SDimitry Andric 22840b57cec5SDimitry Andric StructuredData::Generic *generic = implementor_sp->GetAsGeneric(); 22850b57cec5SDimitry Andric if (!generic) 22860b57cec5SDimitry Andric return lldb::ValueObjectSP(); 22874824e7fdSDimitry Andric auto *implementor = static_cast<PyObject *>(generic->GetValue()); 22880b57cec5SDimitry Andric if (!implementor) 22890b57cec5SDimitry Andric return lldb::ValueObjectSP(); 22900b57cec5SDimitry Andric 22910b57cec5SDimitry Andric lldb::ValueObjectSP ret_val; 22920b57cec5SDimitry Andric { 22930b57cec5SDimitry Andric Locker py_lock(this, 22940b57cec5SDimitry Andric Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); 2295*fe013be4SDimitry Andric PyObject *child_ptr = 2296*fe013be4SDimitry Andric SWIGBridge::LLDBSwigPython_GetChildAtIndex(implementor, idx); 22970b57cec5SDimitry Andric if (child_ptr != nullptr && child_ptr != Py_None) { 22980b57cec5SDimitry Andric lldb::SBValue *sb_value_ptr = 22990b57cec5SDimitry Andric (lldb::SBValue *)LLDBSWIGPython_CastPyObjectToSBValue(child_ptr); 23000b57cec5SDimitry Andric if (sb_value_ptr == nullptr) 23010b57cec5SDimitry Andric Py_XDECREF(child_ptr); 23020b57cec5SDimitry Andric else 2303*fe013be4SDimitry Andric ret_val = SWIGBridge::LLDBSWIGPython_GetValueObjectSPFromSBValue( 2304*fe013be4SDimitry Andric sb_value_ptr); 23050b57cec5SDimitry Andric } else { 23060b57cec5SDimitry Andric Py_XDECREF(child_ptr); 23070b57cec5SDimitry Andric } 23080b57cec5SDimitry Andric } 23090b57cec5SDimitry Andric 23100b57cec5SDimitry Andric return ret_val; 23110b57cec5SDimitry Andric } 23120b57cec5SDimitry Andric 23130b57cec5SDimitry Andric int ScriptInterpreterPythonImpl::GetIndexOfChildWithName( 23140b57cec5SDimitry Andric const StructuredData::ObjectSP &implementor_sp, const char *child_name) { 23150b57cec5SDimitry Andric if (!implementor_sp) 23160b57cec5SDimitry Andric return UINT32_MAX; 23170b57cec5SDimitry Andric 23180b57cec5SDimitry Andric StructuredData::Generic *generic = implementor_sp->GetAsGeneric(); 23190b57cec5SDimitry Andric if (!generic) 23200b57cec5SDimitry Andric return UINT32_MAX; 23214824e7fdSDimitry Andric auto *implementor = static_cast<PyObject *>(generic->GetValue()); 23220b57cec5SDimitry Andric if (!implementor) 23230b57cec5SDimitry Andric return UINT32_MAX; 23240b57cec5SDimitry Andric 23250b57cec5SDimitry Andric int ret_val = UINT32_MAX; 23260b57cec5SDimitry Andric 23270b57cec5SDimitry Andric { 23280b57cec5SDimitry Andric Locker py_lock(this, 23290b57cec5SDimitry Andric Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); 2330*fe013be4SDimitry Andric ret_val = SWIGBridge::LLDBSwigPython_GetIndexOfChildWithName(implementor, child_name); 23310b57cec5SDimitry Andric } 23320b57cec5SDimitry Andric 23330b57cec5SDimitry Andric return ret_val; 23340b57cec5SDimitry Andric } 23350b57cec5SDimitry Andric 23360b57cec5SDimitry Andric bool ScriptInterpreterPythonImpl::UpdateSynthProviderInstance( 23370b57cec5SDimitry Andric const StructuredData::ObjectSP &implementor_sp) { 23380b57cec5SDimitry Andric bool ret_val = false; 23390b57cec5SDimitry Andric 23400b57cec5SDimitry Andric if (!implementor_sp) 23410b57cec5SDimitry Andric return ret_val; 23420b57cec5SDimitry Andric 23430b57cec5SDimitry Andric StructuredData::Generic *generic = implementor_sp->GetAsGeneric(); 23440b57cec5SDimitry Andric if (!generic) 23450b57cec5SDimitry Andric return ret_val; 23464824e7fdSDimitry Andric auto *implementor = static_cast<PyObject *>(generic->GetValue()); 23470b57cec5SDimitry Andric if (!implementor) 23480b57cec5SDimitry Andric return ret_val; 23490b57cec5SDimitry Andric 23500b57cec5SDimitry Andric { 23510b57cec5SDimitry Andric Locker py_lock(this, 23520b57cec5SDimitry Andric Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); 2353*fe013be4SDimitry Andric ret_val = 2354*fe013be4SDimitry Andric SWIGBridge::LLDBSwigPython_UpdateSynthProviderInstance(implementor); 23550b57cec5SDimitry Andric } 23560b57cec5SDimitry Andric 23570b57cec5SDimitry Andric return ret_val; 23580b57cec5SDimitry Andric } 23590b57cec5SDimitry Andric 23600b57cec5SDimitry Andric bool ScriptInterpreterPythonImpl::MightHaveChildrenSynthProviderInstance( 23610b57cec5SDimitry Andric const StructuredData::ObjectSP &implementor_sp) { 23620b57cec5SDimitry Andric bool ret_val = false; 23630b57cec5SDimitry Andric 23640b57cec5SDimitry Andric if (!implementor_sp) 23650b57cec5SDimitry Andric return ret_val; 23660b57cec5SDimitry Andric 23670b57cec5SDimitry Andric StructuredData::Generic *generic = implementor_sp->GetAsGeneric(); 23680b57cec5SDimitry Andric if (!generic) 23690b57cec5SDimitry Andric return ret_val; 23704824e7fdSDimitry Andric auto *implementor = static_cast<PyObject *>(generic->GetValue()); 23710b57cec5SDimitry Andric if (!implementor) 23720b57cec5SDimitry Andric return ret_val; 23730b57cec5SDimitry Andric 23740b57cec5SDimitry Andric { 23750b57cec5SDimitry Andric Locker py_lock(this, 23760b57cec5SDimitry Andric Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); 2377*fe013be4SDimitry Andric ret_val = SWIGBridge::LLDBSwigPython_MightHaveChildrenSynthProviderInstance( 2378*fe013be4SDimitry Andric implementor); 23790b57cec5SDimitry Andric } 23800b57cec5SDimitry Andric 23810b57cec5SDimitry Andric return ret_val; 23820b57cec5SDimitry Andric } 23830b57cec5SDimitry Andric 23840b57cec5SDimitry Andric lldb::ValueObjectSP ScriptInterpreterPythonImpl::GetSyntheticValue( 23850b57cec5SDimitry Andric const StructuredData::ObjectSP &implementor_sp) { 23860b57cec5SDimitry Andric lldb::ValueObjectSP ret_val(nullptr); 23870b57cec5SDimitry Andric 23880b57cec5SDimitry Andric if (!implementor_sp) 23890b57cec5SDimitry Andric return ret_val; 23900b57cec5SDimitry Andric 23910b57cec5SDimitry Andric StructuredData::Generic *generic = implementor_sp->GetAsGeneric(); 23920b57cec5SDimitry Andric if (!generic) 23930b57cec5SDimitry Andric return ret_val; 23944824e7fdSDimitry Andric auto *implementor = static_cast<PyObject *>(generic->GetValue()); 23950b57cec5SDimitry Andric if (!implementor) 23960b57cec5SDimitry Andric return ret_val; 23970b57cec5SDimitry Andric 23980b57cec5SDimitry Andric { 23990b57cec5SDimitry Andric Locker py_lock(this, 24000b57cec5SDimitry Andric Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); 24014824e7fdSDimitry Andric PyObject *child_ptr = 2402*fe013be4SDimitry Andric SWIGBridge::LLDBSwigPython_GetValueSynthProviderInstance(implementor); 24030b57cec5SDimitry Andric if (child_ptr != nullptr && child_ptr != Py_None) { 24040b57cec5SDimitry Andric lldb::SBValue *sb_value_ptr = 24050b57cec5SDimitry Andric (lldb::SBValue *)LLDBSWIGPython_CastPyObjectToSBValue(child_ptr); 24060b57cec5SDimitry Andric if (sb_value_ptr == nullptr) 24070b57cec5SDimitry Andric Py_XDECREF(child_ptr); 24080b57cec5SDimitry Andric else 2409*fe013be4SDimitry Andric ret_val = SWIGBridge::LLDBSWIGPython_GetValueObjectSPFromSBValue( 2410*fe013be4SDimitry Andric sb_value_ptr); 24110b57cec5SDimitry Andric } else { 24120b57cec5SDimitry Andric Py_XDECREF(child_ptr); 24130b57cec5SDimitry Andric } 24140b57cec5SDimitry Andric } 24150b57cec5SDimitry Andric 24160b57cec5SDimitry Andric return ret_val; 24170b57cec5SDimitry Andric } 24180b57cec5SDimitry Andric 24190b57cec5SDimitry Andric ConstString ScriptInterpreterPythonImpl::GetSyntheticTypeName( 24200b57cec5SDimitry Andric const StructuredData::ObjectSP &implementor_sp) { 24210b57cec5SDimitry Andric Locker py_lock(this, 24220b57cec5SDimitry Andric Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); 24230b57cec5SDimitry Andric 2424bdd1243dSDimitry Andric if (!implementor_sp) 2425bdd1243dSDimitry Andric return {}; 2426bdd1243dSDimitry Andric 2427bdd1243dSDimitry Andric StructuredData::Generic *generic = implementor_sp->GetAsGeneric(); 2428bdd1243dSDimitry Andric if (!generic) 2429bdd1243dSDimitry Andric return {}; 2430bdd1243dSDimitry Andric 2431bdd1243dSDimitry Andric PythonObject implementor(PyRefType::Borrowed, 2432bdd1243dSDimitry Andric (PyObject *)generic->GetValue()); 2433bdd1243dSDimitry Andric if (!implementor.IsAllocated()) 2434bdd1243dSDimitry Andric return {}; 2435bdd1243dSDimitry Andric 2436bdd1243dSDimitry Andric llvm::Expected<PythonObject> expected_py_return = 2437bdd1243dSDimitry Andric implementor.CallMethod("get_type_name"); 2438bdd1243dSDimitry Andric 2439bdd1243dSDimitry Andric if (!expected_py_return) { 2440bdd1243dSDimitry Andric llvm::consumeError(expected_py_return.takeError()); 2441bdd1243dSDimitry Andric return {}; 2442bdd1243dSDimitry Andric } 2443bdd1243dSDimitry Andric 2444bdd1243dSDimitry Andric PythonObject py_return = std::move(expected_py_return.get()); 24450b57cec5SDimitry Andric 24460b57cec5SDimitry Andric ConstString ret_val; 24470b57cec5SDimitry Andric bool got_string = false; 24480b57cec5SDimitry Andric std::string buffer; 24490b57cec5SDimitry Andric 24500b57cec5SDimitry Andric if (py_return.IsAllocated() && PythonString::Check(py_return.get())) { 24510b57cec5SDimitry Andric PythonString py_string(PyRefType::Borrowed, py_return.get()); 24520b57cec5SDimitry Andric llvm::StringRef return_data(py_string.GetString()); 24530b57cec5SDimitry Andric if (!return_data.empty()) { 24540b57cec5SDimitry Andric buffer.assign(return_data.data(), return_data.size()); 24550b57cec5SDimitry Andric got_string = true; 24560b57cec5SDimitry Andric } 24570b57cec5SDimitry Andric } 24580b57cec5SDimitry Andric 24590b57cec5SDimitry Andric if (got_string) 24600b57cec5SDimitry Andric ret_val.SetCStringWithLength(buffer.c_str(), buffer.size()); 24610b57cec5SDimitry Andric 24620b57cec5SDimitry Andric return ret_val; 24630b57cec5SDimitry Andric } 24640b57cec5SDimitry Andric 24650b57cec5SDimitry Andric bool ScriptInterpreterPythonImpl::RunScriptFormatKeyword( 24660b57cec5SDimitry Andric const char *impl_function, Process *process, std::string &output, 24670b57cec5SDimitry Andric Status &error) { 24680b57cec5SDimitry Andric bool ret_val; 24690b57cec5SDimitry Andric if (!process) { 24700b57cec5SDimitry Andric error.SetErrorString("no process"); 24710b57cec5SDimitry Andric return false; 24720b57cec5SDimitry Andric } 24730b57cec5SDimitry Andric if (!impl_function || !impl_function[0]) { 24740b57cec5SDimitry Andric error.SetErrorString("no function to execute"); 24750b57cec5SDimitry Andric return false; 24760b57cec5SDimitry Andric } 24770b57cec5SDimitry Andric 24780b57cec5SDimitry Andric { 24790b57cec5SDimitry Andric Locker py_lock(this, 24800b57cec5SDimitry Andric Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); 2481*fe013be4SDimitry Andric ret_val = SWIGBridge::LLDBSWIGPythonRunScriptKeywordProcess( 24824824e7fdSDimitry Andric impl_function, m_dictionary_name.c_str(), process->shared_from_this(), 24834824e7fdSDimitry Andric output); 24840b57cec5SDimitry Andric if (!ret_val) 24850b57cec5SDimitry Andric error.SetErrorString("python script evaluation failed"); 24860b57cec5SDimitry Andric } 24870b57cec5SDimitry Andric return ret_val; 24880b57cec5SDimitry Andric } 24890b57cec5SDimitry Andric 24900b57cec5SDimitry Andric bool ScriptInterpreterPythonImpl::RunScriptFormatKeyword( 24910b57cec5SDimitry Andric const char *impl_function, Thread *thread, std::string &output, 24920b57cec5SDimitry Andric Status &error) { 24930b57cec5SDimitry Andric if (!thread) { 24940b57cec5SDimitry Andric error.SetErrorString("no thread"); 24950b57cec5SDimitry Andric return false; 24960b57cec5SDimitry Andric } 24970b57cec5SDimitry Andric if (!impl_function || !impl_function[0]) { 24980b57cec5SDimitry Andric error.SetErrorString("no function to execute"); 24990b57cec5SDimitry Andric return false; 25000b57cec5SDimitry Andric } 25010b57cec5SDimitry Andric 25020b57cec5SDimitry Andric Locker py_lock(this, 25030b57cec5SDimitry Andric Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); 2504*fe013be4SDimitry Andric if (std::optional<std::string> result = 2505*fe013be4SDimitry Andric SWIGBridge::LLDBSWIGPythonRunScriptKeywordThread( 25060eae32dcSDimitry Andric impl_function, m_dictionary_name.c_str(), 25070eae32dcSDimitry Andric thread->shared_from_this())) { 25080eae32dcSDimitry Andric output = std::move(*result); 25090eae32dcSDimitry Andric return true; 25100b57cec5SDimitry Andric } 25110eae32dcSDimitry Andric error.SetErrorString("python script evaluation failed"); 25120eae32dcSDimitry Andric return false; 25130b57cec5SDimitry Andric } 25140b57cec5SDimitry Andric 25150b57cec5SDimitry Andric bool ScriptInterpreterPythonImpl::RunScriptFormatKeyword( 25160b57cec5SDimitry Andric const char *impl_function, Target *target, std::string &output, 25170b57cec5SDimitry Andric Status &error) { 25180b57cec5SDimitry Andric bool ret_val; 25190b57cec5SDimitry Andric if (!target) { 25200b57cec5SDimitry Andric error.SetErrorString("no thread"); 25210b57cec5SDimitry Andric return false; 25220b57cec5SDimitry Andric } 25230b57cec5SDimitry Andric if (!impl_function || !impl_function[0]) { 25240b57cec5SDimitry Andric error.SetErrorString("no function to execute"); 25250b57cec5SDimitry Andric return false; 25260b57cec5SDimitry Andric } 25270b57cec5SDimitry Andric 25280b57cec5SDimitry Andric { 25290b57cec5SDimitry Andric TargetSP target_sp(target->shared_from_this()); 25300b57cec5SDimitry Andric Locker py_lock(this, 25310b57cec5SDimitry Andric Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); 2532*fe013be4SDimitry Andric ret_val = SWIGBridge::LLDBSWIGPythonRunScriptKeywordTarget( 25330b57cec5SDimitry Andric impl_function, m_dictionary_name.c_str(), target_sp, output); 25340b57cec5SDimitry Andric if (!ret_val) 25350b57cec5SDimitry Andric error.SetErrorString("python script evaluation failed"); 25360b57cec5SDimitry Andric } 25370b57cec5SDimitry Andric return ret_val; 25380b57cec5SDimitry Andric } 25390b57cec5SDimitry Andric 25400b57cec5SDimitry Andric bool ScriptInterpreterPythonImpl::RunScriptFormatKeyword( 25410b57cec5SDimitry Andric const char *impl_function, StackFrame *frame, std::string &output, 25420b57cec5SDimitry Andric Status &error) { 25430b57cec5SDimitry Andric if (!frame) { 25440b57cec5SDimitry Andric error.SetErrorString("no frame"); 25450b57cec5SDimitry Andric return false; 25460b57cec5SDimitry Andric } 25470b57cec5SDimitry Andric if (!impl_function || !impl_function[0]) { 25480b57cec5SDimitry Andric error.SetErrorString("no function to execute"); 25490b57cec5SDimitry Andric return false; 25500b57cec5SDimitry Andric } 25510b57cec5SDimitry Andric 25520b57cec5SDimitry Andric Locker py_lock(this, 25530b57cec5SDimitry Andric Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); 2554*fe013be4SDimitry Andric if (std::optional<std::string> result = 2555*fe013be4SDimitry Andric SWIGBridge::LLDBSWIGPythonRunScriptKeywordFrame( 25560eae32dcSDimitry Andric impl_function, m_dictionary_name.c_str(), 25570eae32dcSDimitry Andric frame->shared_from_this())) { 25580eae32dcSDimitry Andric output = std::move(*result); 25590eae32dcSDimitry Andric return true; 25600b57cec5SDimitry Andric } 25610eae32dcSDimitry Andric error.SetErrorString("python script evaluation failed"); 25620eae32dcSDimitry Andric return false; 25630b57cec5SDimitry Andric } 25640b57cec5SDimitry Andric 25650b57cec5SDimitry Andric bool ScriptInterpreterPythonImpl::RunScriptFormatKeyword( 25660b57cec5SDimitry Andric const char *impl_function, ValueObject *value, std::string &output, 25670b57cec5SDimitry Andric Status &error) { 25680b57cec5SDimitry Andric bool ret_val; 25690b57cec5SDimitry Andric if (!value) { 25700b57cec5SDimitry Andric error.SetErrorString("no value"); 25710b57cec5SDimitry Andric return false; 25720b57cec5SDimitry Andric } 25730b57cec5SDimitry Andric if (!impl_function || !impl_function[0]) { 25740b57cec5SDimitry Andric error.SetErrorString("no function to execute"); 25750b57cec5SDimitry Andric return false; 25760b57cec5SDimitry Andric } 25770b57cec5SDimitry Andric 25780b57cec5SDimitry Andric { 25790b57cec5SDimitry Andric Locker py_lock(this, 25800b57cec5SDimitry Andric Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); 2581*fe013be4SDimitry Andric ret_val = SWIGBridge::LLDBSWIGPythonRunScriptKeywordValue( 25824824e7fdSDimitry Andric impl_function, m_dictionary_name.c_str(), value->GetSP(), output); 25830b57cec5SDimitry Andric if (!ret_val) 25840b57cec5SDimitry Andric error.SetErrorString("python script evaluation failed"); 25850b57cec5SDimitry Andric } 25860b57cec5SDimitry Andric return ret_val; 25870b57cec5SDimitry Andric } 25880b57cec5SDimitry Andric 25890b57cec5SDimitry Andric uint64_t replace_all(std::string &str, const std::string &oldStr, 25900b57cec5SDimitry Andric const std::string &newStr) { 25910b57cec5SDimitry Andric size_t pos = 0; 25920b57cec5SDimitry Andric uint64_t matches = 0; 25930b57cec5SDimitry Andric while ((pos = str.find(oldStr, pos)) != std::string::npos) { 25940b57cec5SDimitry Andric matches++; 25950b57cec5SDimitry Andric str.replace(pos, oldStr.length(), newStr); 25960b57cec5SDimitry Andric pos += newStr.length(); 25970b57cec5SDimitry Andric } 25980b57cec5SDimitry Andric return matches; 25990b57cec5SDimitry Andric } 26000b57cec5SDimitry Andric 26010b57cec5SDimitry Andric bool ScriptInterpreterPythonImpl::LoadScriptingModule( 2602fe6060f1SDimitry Andric const char *pathname, const LoadScriptOptions &options, 2603fe6060f1SDimitry Andric lldb_private::Status &error, StructuredData::ObjectSP *module_sp, 2604fe6060f1SDimitry Andric FileSpec extra_search_dir) { 2605e8d8bef9SDimitry Andric namespace fs = llvm::sys::fs; 2606e8d8bef9SDimitry Andric namespace path = llvm::sys::path; 2607e8d8bef9SDimitry Andric 2608fe6060f1SDimitry Andric ExecuteScriptOptions exc_options = ExecuteScriptOptions() 2609fe6060f1SDimitry Andric .SetEnableIO(!options.GetSilent()) 2610fe6060f1SDimitry Andric .SetSetLLDBGlobals(false); 2611fe6060f1SDimitry Andric 26120b57cec5SDimitry Andric if (!pathname || !pathname[0]) { 2613fcaf7f86SDimitry Andric error.SetErrorString("empty path"); 26140b57cec5SDimitry Andric return false; 26150b57cec5SDimitry Andric } 26160b57cec5SDimitry Andric 2617fe6060f1SDimitry Andric llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>> 2618fe6060f1SDimitry Andric io_redirect_or_error = ScriptInterpreterIORedirect::Create( 2619fe6060f1SDimitry Andric exc_options.GetEnableIO(), m_debugger, /*result=*/nullptr); 2620fe6060f1SDimitry Andric 2621fe6060f1SDimitry Andric if (!io_redirect_or_error) { 2622fe6060f1SDimitry Andric error = io_redirect_or_error.takeError(); 2623fe6060f1SDimitry Andric return false; 2624fe6060f1SDimitry Andric } 2625fe6060f1SDimitry Andric 2626fe6060f1SDimitry Andric ScriptInterpreterIORedirect &io_redirect = **io_redirect_or_error; 26270b57cec5SDimitry Andric 26280b57cec5SDimitry Andric // Before executing Python code, lock the GIL. 26290b57cec5SDimitry Andric Locker py_lock(this, 26300b57cec5SDimitry Andric Locker::AcquireLock | 2631fe6060f1SDimitry Andric (options.GetInitSession() ? Locker::InitSession : 0) | 2632fe6060f1SDimitry Andric Locker::NoSTDIN, 26330b57cec5SDimitry Andric Locker::FreeAcquiredLock | 2634fe6060f1SDimitry Andric (options.GetInitSession() ? Locker::TearDownSession : 0), 2635fe6060f1SDimitry Andric io_redirect.GetInputFile(), io_redirect.GetOutputFile(), 2636fe6060f1SDimitry Andric io_redirect.GetErrorFile()); 26370b57cec5SDimitry Andric 2638fe6060f1SDimitry Andric auto ExtendSysPath = [&](std::string directory) -> llvm::Error { 2639e8d8bef9SDimitry Andric if (directory.empty()) { 2640e8d8bef9SDimitry Andric return llvm::make_error<llvm::StringError>( 2641e8d8bef9SDimitry Andric "invalid directory name", llvm::inconvertibleErrorCode()); 26420b57cec5SDimitry Andric } 26430b57cec5SDimitry Andric 26440b57cec5SDimitry Andric replace_all(directory, "\\", "\\\\"); 26450b57cec5SDimitry Andric replace_all(directory, "'", "\\'"); 26460b57cec5SDimitry Andric 2647e8d8bef9SDimitry Andric // Make sure that Python has "directory" in the search path. 26480b57cec5SDimitry Andric StreamString command_stream; 26490b57cec5SDimitry Andric command_stream.Printf("if not (sys.path.__contains__('%s')):\n " 26500b57cec5SDimitry Andric "sys.path.insert(1,'%s');\n\n", 26510b57cec5SDimitry Andric directory.c_str(), directory.c_str()); 26520b57cec5SDimitry Andric bool syspath_retval = 2653fe6060f1SDimitry Andric ExecuteMultipleLines(command_stream.GetData(), exc_options).Success(); 26540b57cec5SDimitry Andric if (!syspath_retval) { 2655e8d8bef9SDimitry Andric return llvm::make_error<llvm::StringError>( 2656e8d8bef9SDimitry Andric "Python sys.path handling failed", llvm::inconvertibleErrorCode()); 26570b57cec5SDimitry Andric } 26580b57cec5SDimitry Andric 2659e8d8bef9SDimitry Andric return llvm::Error::success(); 2660e8d8bef9SDimitry Andric }; 2661e8d8bef9SDimitry Andric 2662e8d8bef9SDimitry Andric std::string module_name(pathname); 2663fe6060f1SDimitry Andric bool possible_package = false; 2664e8d8bef9SDimitry Andric 2665e8d8bef9SDimitry Andric if (extra_search_dir) { 2666e8d8bef9SDimitry Andric if (llvm::Error e = ExtendSysPath(extra_search_dir.GetPath())) { 2667e8d8bef9SDimitry Andric error = std::move(e); 2668e8d8bef9SDimitry Andric return false; 26690b57cec5SDimitry Andric } 26700b57cec5SDimitry Andric } else { 2671e8d8bef9SDimitry Andric FileSpec module_file(pathname); 2672e8d8bef9SDimitry Andric FileSystem::Instance().Resolve(module_file); 2673e8d8bef9SDimitry Andric 2674e8d8bef9SDimitry Andric fs::file_status st; 2675e8d8bef9SDimitry Andric std::error_code ec = status(module_file.GetPath(), st); 2676e8d8bef9SDimitry Andric 2677e8d8bef9SDimitry Andric if (ec || st.type() == fs::file_type::status_error || 2678e8d8bef9SDimitry Andric st.type() == fs::file_type::type_unknown || 2679e8d8bef9SDimitry Andric st.type() == fs::file_type::file_not_found) { 2680e8d8bef9SDimitry Andric // if not a valid file of any sort, check if it might be a filename still 2681e8d8bef9SDimitry Andric // dot can't be used but / and \ can, and if either is found, reject 2682e8d8bef9SDimitry Andric if (strchr(pathname, '\\') || strchr(pathname, '/')) { 2683fcaf7f86SDimitry Andric error.SetErrorStringWithFormatv("invalid pathname '{0}'", pathname); 2684e8d8bef9SDimitry Andric return false; 2685e8d8bef9SDimitry Andric } 2686e8d8bef9SDimitry Andric // Not a filename, probably a package of some sort, let it go through. 2687fe6060f1SDimitry Andric possible_package = true; 2688e8d8bef9SDimitry Andric } else if (is_directory(st) || is_regular_file(st)) { 2689e8d8bef9SDimitry Andric if (module_file.GetDirectory().IsEmpty()) { 2690fcaf7f86SDimitry Andric error.SetErrorStringWithFormatv("invalid directory name '{0}'", pathname); 2691e8d8bef9SDimitry Andric return false; 2692e8d8bef9SDimitry Andric } 2693e8d8bef9SDimitry Andric if (llvm::Error e = 2694e8d8bef9SDimitry Andric ExtendSysPath(module_file.GetDirectory().GetCString())) { 2695e8d8bef9SDimitry Andric error = std::move(e); 2696e8d8bef9SDimitry Andric return false; 2697e8d8bef9SDimitry Andric } 2698e8d8bef9SDimitry Andric module_name = module_file.GetFilename().GetCString(); 2699e8d8bef9SDimitry Andric } else { 27000b57cec5SDimitry Andric error.SetErrorString("no known way to import this module specification"); 27010b57cec5SDimitry Andric return false; 27020b57cec5SDimitry Andric } 2703e8d8bef9SDimitry Andric } 2704e8d8bef9SDimitry Andric 2705e8d8bef9SDimitry Andric // Strip .py or .pyc extension 2706e8d8bef9SDimitry Andric llvm::StringRef extension = llvm::sys::path::extension(module_name); 2707e8d8bef9SDimitry Andric if (!extension.empty()) { 2708e8d8bef9SDimitry Andric if (extension == ".py") 2709e8d8bef9SDimitry Andric module_name.resize(module_name.length() - 3); 2710e8d8bef9SDimitry Andric else if (extension == ".pyc") 2711e8d8bef9SDimitry Andric module_name.resize(module_name.length() - 4); 2712e8d8bef9SDimitry Andric } 27130b57cec5SDimitry Andric 2714fe6060f1SDimitry Andric if (!possible_package && module_name.find('.') != llvm::StringRef::npos) { 2715fe6060f1SDimitry Andric error.SetErrorStringWithFormat( 2716fe6060f1SDimitry Andric "Python does not allow dots in module names: %s", module_name.c_str()); 2717fe6060f1SDimitry Andric return false; 2718fe6060f1SDimitry Andric } 2719fe6060f1SDimitry Andric 2720fe6060f1SDimitry Andric if (module_name.find('-') != llvm::StringRef::npos) { 2721fe6060f1SDimitry Andric error.SetErrorStringWithFormat( 2722fe6060f1SDimitry Andric "Python discourages dashes in module names: %s", module_name.c_str()); 2723fe6060f1SDimitry Andric return false; 2724fe6060f1SDimitry Andric } 2725fe6060f1SDimitry Andric 2726fe6060f1SDimitry Andric // Check if the module is already imported. 2727e8d8bef9SDimitry Andric StreamString command_stream; 27280b57cec5SDimitry Andric command_stream.Clear(); 2729e8d8bef9SDimitry Andric command_stream.Printf("sys.modules.__contains__('%s')", module_name.c_str()); 27300b57cec5SDimitry Andric bool does_contain = false; 2731fe6060f1SDimitry Andric // This call will succeed if the module was ever imported in any Debugger in 2732fe6060f1SDimitry Andric // the lifetime of the process in which this LLDB framework is living. 2733fe6060f1SDimitry Andric const bool does_contain_executed = ExecuteOneLineWithReturn( 27340b57cec5SDimitry Andric command_stream.GetData(), 2735fe6060f1SDimitry Andric ScriptInterpreterPythonImpl::eScriptReturnTypeBool, &does_contain, exc_options); 2736fe6060f1SDimitry Andric 2737fe6060f1SDimitry Andric const bool was_imported_globally = does_contain_executed && does_contain; 2738fe6060f1SDimitry Andric const bool was_imported_locally = 2739fe6060f1SDimitry Andric GetSessionDictionary() 2740e8d8bef9SDimitry Andric .GetItemForKey(PythonString(module_name)) 27410b57cec5SDimitry Andric .IsAllocated(); 27420b57cec5SDimitry Andric 27430b57cec5SDimitry Andric // now actually do the import 27440b57cec5SDimitry Andric command_stream.Clear(); 27450b57cec5SDimitry Andric 2746fe6060f1SDimitry Andric if (was_imported_globally || was_imported_locally) { 27470b57cec5SDimitry Andric if (!was_imported_locally) 2748e8d8bef9SDimitry Andric command_stream.Printf("import %s ; reload_module(%s)", 2749e8d8bef9SDimitry Andric module_name.c_str(), module_name.c_str()); 27500b57cec5SDimitry Andric else 2751e8d8bef9SDimitry Andric command_stream.Printf("reload_module(%s)", module_name.c_str()); 27520b57cec5SDimitry Andric } else 2753e8d8bef9SDimitry Andric command_stream.Printf("import %s", module_name.c_str()); 27540b57cec5SDimitry Andric 2755fe6060f1SDimitry Andric error = ExecuteMultipleLines(command_stream.GetData(), exc_options); 27560b57cec5SDimitry Andric if (error.Fail()) 27570b57cec5SDimitry Andric return false; 27580b57cec5SDimitry Andric 27590b57cec5SDimitry Andric // if we are here, everything worked 27600b57cec5SDimitry Andric // call __lldb_init_module(debugger,dict) 2761*fe013be4SDimitry Andric if (!SWIGBridge::LLDBSwigPythonCallModuleInit( 2762*fe013be4SDimitry Andric module_name.c_str(), m_dictionary_name.c_str(), 27630eae32dcSDimitry Andric m_debugger.shared_from_this())) { 27640b57cec5SDimitry Andric error.SetErrorString("calling __lldb_init_module failed"); 27650b57cec5SDimitry Andric return false; 27660b57cec5SDimitry Andric } 27670b57cec5SDimitry Andric 27680b57cec5SDimitry Andric if (module_sp) { 27690b57cec5SDimitry Andric // everything went just great, now set the module object 27700b57cec5SDimitry Andric command_stream.Clear(); 2771e8d8bef9SDimitry Andric command_stream.Printf("%s", module_name.c_str()); 27720b57cec5SDimitry Andric void *module_pyobj = nullptr; 27730b57cec5SDimitry Andric if (ExecuteOneLineWithReturn( 27740b57cec5SDimitry Andric command_stream.GetData(), 2775fe6060f1SDimitry Andric ScriptInterpreter::eScriptReturnTypeOpaqueObject, &module_pyobj, 2776fe6060f1SDimitry Andric exc_options) && 27770b57cec5SDimitry Andric module_pyobj) 277804eeddc0SDimitry Andric *module_sp = std::make_shared<StructuredPythonObject>(PythonObject( 277904eeddc0SDimitry Andric PyRefType::Owned, static_cast<PyObject *>(module_pyobj))); 27800b57cec5SDimitry Andric } 27810b57cec5SDimitry Andric 27820b57cec5SDimitry Andric return true; 27830b57cec5SDimitry Andric } 27840b57cec5SDimitry Andric 27850b57cec5SDimitry Andric bool ScriptInterpreterPythonImpl::IsReservedWord(const char *word) { 27860b57cec5SDimitry Andric if (!word || !word[0]) 27870b57cec5SDimitry Andric return false; 27880b57cec5SDimitry Andric 27890b57cec5SDimitry Andric llvm::StringRef word_sr(word); 27900b57cec5SDimitry Andric 27910b57cec5SDimitry Andric // filter out a few characters that would just confuse us and that are 27920b57cec5SDimitry Andric // clearly not keyword material anyway 27930b57cec5SDimitry Andric if (word_sr.find('"') != llvm::StringRef::npos || 27940b57cec5SDimitry Andric word_sr.find('\'') != llvm::StringRef::npos) 27950b57cec5SDimitry Andric return false; 27960b57cec5SDimitry Andric 27970b57cec5SDimitry Andric StreamString command_stream; 27980b57cec5SDimitry Andric command_stream.Printf("keyword.iskeyword('%s')", word); 27990b57cec5SDimitry Andric bool result; 28000b57cec5SDimitry Andric ExecuteScriptOptions options; 28010b57cec5SDimitry Andric options.SetEnableIO(false); 28020b57cec5SDimitry Andric options.SetMaskoutErrors(true); 28030b57cec5SDimitry Andric options.SetSetLLDBGlobals(false); 28040b57cec5SDimitry Andric if (ExecuteOneLineWithReturn(command_stream.GetData(), 28050b57cec5SDimitry Andric ScriptInterpreter::eScriptReturnTypeBool, 28060b57cec5SDimitry Andric &result, options)) 28070b57cec5SDimitry Andric return result; 28080b57cec5SDimitry Andric return false; 28090b57cec5SDimitry Andric } 28100b57cec5SDimitry Andric 28110b57cec5SDimitry Andric ScriptInterpreterPythonImpl::SynchronicityHandler::SynchronicityHandler( 28120b57cec5SDimitry Andric lldb::DebuggerSP debugger_sp, ScriptedCommandSynchronicity synchro) 28130b57cec5SDimitry Andric : m_debugger_sp(debugger_sp), m_synch_wanted(synchro), 28140b57cec5SDimitry Andric m_old_asynch(debugger_sp->GetAsyncExecution()) { 28150b57cec5SDimitry Andric if (m_synch_wanted == eScriptedCommandSynchronicitySynchronous) 28160b57cec5SDimitry Andric m_debugger_sp->SetAsyncExecution(false); 28170b57cec5SDimitry Andric else if (m_synch_wanted == eScriptedCommandSynchronicityAsynchronous) 28180b57cec5SDimitry Andric m_debugger_sp->SetAsyncExecution(true); 28190b57cec5SDimitry Andric } 28200b57cec5SDimitry Andric 28210b57cec5SDimitry Andric ScriptInterpreterPythonImpl::SynchronicityHandler::~SynchronicityHandler() { 28220b57cec5SDimitry Andric if (m_synch_wanted != eScriptedCommandSynchronicityCurrentValue) 28230b57cec5SDimitry Andric m_debugger_sp->SetAsyncExecution(m_old_asynch); 28240b57cec5SDimitry Andric } 28250b57cec5SDimitry Andric 28260b57cec5SDimitry Andric bool ScriptInterpreterPythonImpl::RunScriptBasedCommand( 28270b57cec5SDimitry Andric const char *impl_function, llvm::StringRef args, 28280b57cec5SDimitry Andric ScriptedCommandSynchronicity synchronicity, 28290b57cec5SDimitry Andric lldb_private::CommandReturnObject &cmd_retobj, Status &error, 28300b57cec5SDimitry Andric const lldb_private::ExecutionContext &exe_ctx) { 28310b57cec5SDimitry Andric if (!impl_function) { 28320b57cec5SDimitry Andric error.SetErrorString("no function to execute"); 28330b57cec5SDimitry Andric return false; 28340b57cec5SDimitry Andric } 28350b57cec5SDimitry Andric 28360b57cec5SDimitry Andric lldb::DebuggerSP debugger_sp = m_debugger.shared_from_this(); 28370b57cec5SDimitry Andric lldb::ExecutionContextRefSP exe_ctx_ref_sp(new ExecutionContextRef(exe_ctx)); 28380b57cec5SDimitry Andric 28390b57cec5SDimitry Andric if (!debugger_sp.get()) { 28400b57cec5SDimitry Andric error.SetErrorString("invalid Debugger pointer"); 28410b57cec5SDimitry Andric return false; 28420b57cec5SDimitry Andric } 28430b57cec5SDimitry Andric 28440b57cec5SDimitry Andric bool ret_val = false; 28450b57cec5SDimitry Andric 28460b57cec5SDimitry Andric std::string err_msg; 28470b57cec5SDimitry Andric 28480b57cec5SDimitry Andric { 28490b57cec5SDimitry Andric Locker py_lock(this, 28500b57cec5SDimitry Andric Locker::AcquireLock | Locker::InitSession | 28510b57cec5SDimitry Andric (cmd_retobj.GetInteractive() ? 0 : Locker::NoSTDIN), 28520b57cec5SDimitry Andric Locker::FreeLock | Locker::TearDownSession); 28530b57cec5SDimitry Andric 28540b57cec5SDimitry Andric SynchronicityHandler synch_handler(debugger_sp, synchronicity); 28550b57cec5SDimitry Andric 28560b57cec5SDimitry Andric std::string args_str = args.str(); 2857*fe013be4SDimitry Andric ret_val = SWIGBridge::LLDBSwigPythonCallCommand( 28580b57cec5SDimitry Andric impl_function, m_dictionary_name.c_str(), debugger_sp, args_str.c_str(), 28590b57cec5SDimitry Andric cmd_retobj, exe_ctx_ref_sp); 28600b57cec5SDimitry Andric } 28610b57cec5SDimitry Andric 28620b57cec5SDimitry Andric if (!ret_val) 28630b57cec5SDimitry Andric error.SetErrorString("unable to execute script function"); 2864bdd1243dSDimitry Andric else if (cmd_retobj.GetStatus() == eReturnStatusFailed) 2865bdd1243dSDimitry Andric return false; 28660b57cec5SDimitry Andric 2867bdd1243dSDimitry Andric error.Clear(); 28680b57cec5SDimitry Andric return ret_val; 28690b57cec5SDimitry Andric } 28700b57cec5SDimitry Andric 28710b57cec5SDimitry Andric bool ScriptInterpreterPythonImpl::RunScriptBasedCommand( 28720b57cec5SDimitry Andric StructuredData::GenericSP impl_obj_sp, llvm::StringRef args, 28730b57cec5SDimitry Andric ScriptedCommandSynchronicity synchronicity, 28740b57cec5SDimitry Andric lldb_private::CommandReturnObject &cmd_retobj, Status &error, 28750b57cec5SDimitry Andric const lldb_private::ExecutionContext &exe_ctx) { 28760b57cec5SDimitry Andric if (!impl_obj_sp || !impl_obj_sp->IsValid()) { 28770b57cec5SDimitry Andric error.SetErrorString("no function to execute"); 28780b57cec5SDimitry Andric return false; 28790b57cec5SDimitry Andric } 28800b57cec5SDimitry Andric 28810b57cec5SDimitry Andric lldb::DebuggerSP debugger_sp = m_debugger.shared_from_this(); 28820b57cec5SDimitry Andric lldb::ExecutionContextRefSP exe_ctx_ref_sp(new ExecutionContextRef(exe_ctx)); 28830b57cec5SDimitry Andric 28840b57cec5SDimitry Andric if (!debugger_sp.get()) { 28850b57cec5SDimitry Andric error.SetErrorString("invalid Debugger pointer"); 28860b57cec5SDimitry Andric return false; 28870b57cec5SDimitry Andric } 28880b57cec5SDimitry Andric 28890b57cec5SDimitry Andric bool ret_val = false; 28900b57cec5SDimitry Andric 28910b57cec5SDimitry Andric std::string err_msg; 28920b57cec5SDimitry Andric 28930b57cec5SDimitry Andric { 28940b57cec5SDimitry Andric Locker py_lock(this, 28950b57cec5SDimitry Andric Locker::AcquireLock | Locker::InitSession | 28960b57cec5SDimitry Andric (cmd_retobj.GetInteractive() ? 0 : Locker::NoSTDIN), 28970b57cec5SDimitry Andric Locker::FreeLock | Locker::TearDownSession); 28980b57cec5SDimitry Andric 28990b57cec5SDimitry Andric SynchronicityHandler synch_handler(debugger_sp, synchronicity); 29000b57cec5SDimitry Andric 29010b57cec5SDimitry Andric std::string args_str = args.str(); 2902*fe013be4SDimitry Andric ret_val = SWIGBridge::LLDBSwigPythonCallCommandObject( 29034824e7fdSDimitry Andric static_cast<PyObject *>(impl_obj_sp->GetValue()), debugger_sp, 29044824e7fdSDimitry Andric args_str.c_str(), cmd_retobj, exe_ctx_ref_sp); 29050b57cec5SDimitry Andric } 29060b57cec5SDimitry Andric 29070b57cec5SDimitry Andric if (!ret_val) 29080b57cec5SDimitry Andric error.SetErrorString("unable to execute script function"); 2909bdd1243dSDimitry Andric else if (cmd_retobj.GetStatus() == eReturnStatusFailed) 2910bdd1243dSDimitry Andric return false; 29110b57cec5SDimitry Andric 2912bdd1243dSDimitry Andric error.Clear(); 29130b57cec5SDimitry Andric return ret_val; 29140b57cec5SDimitry Andric } 29150b57cec5SDimitry Andric 29165ffd83dbSDimitry Andric /// In Python, a special attribute __doc__ contains the docstring for an object 29175ffd83dbSDimitry Andric /// (function, method, class, ...) if any is defined Otherwise, the attribute's 29185ffd83dbSDimitry Andric /// value is None. 29190b57cec5SDimitry Andric bool ScriptInterpreterPythonImpl::GetDocumentationForItem(const char *item, 29200b57cec5SDimitry Andric std::string &dest) { 29210b57cec5SDimitry Andric dest.clear(); 29225ffd83dbSDimitry Andric 29230b57cec5SDimitry Andric if (!item || !*item) 29240b57cec5SDimitry Andric return false; 29255ffd83dbSDimitry Andric 29260b57cec5SDimitry Andric std::string command(item); 29270b57cec5SDimitry Andric command += ".__doc__"; 29280b57cec5SDimitry Andric 29295ffd83dbSDimitry Andric // Python is going to point this to valid data if ExecuteOneLineWithReturn 29305ffd83dbSDimitry Andric // returns successfully. 29315ffd83dbSDimitry Andric char *result_ptr = nullptr; 29320b57cec5SDimitry Andric 29330b57cec5SDimitry Andric if (ExecuteOneLineWithReturn( 29345ffd83dbSDimitry Andric command, ScriptInterpreter::eScriptReturnTypeCharStrOrNone, 29350b57cec5SDimitry Andric &result_ptr, 2936fe6060f1SDimitry Andric ExecuteScriptOptions().SetEnableIO(false))) { 29370b57cec5SDimitry Andric if (result_ptr) 29380b57cec5SDimitry Andric dest.assign(result_ptr); 29390b57cec5SDimitry Andric return true; 29400b57cec5SDimitry Andric } 29415ffd83dbSDimitry Andric 29425ffd83dbSDimitry Andric StreamString str_stream; 29435ffd83dbSDimitry Andric str_stream << "Function " << item 29445ffd83dbSDimitry Andric << " was not found. Containing module might be missing."; 29455ffd83dbSDimitry Andric dest = std::string(str_stream.GetString()); 29465ffd83dbSDimitry Andric 29475ffd83dbSDimitry Andric return false; 29480b57cec5SDimitry Andric } 29490b57cec5SDimitry Andric 29500b57cec5SDimitry Andric bool ScriptInterpreterPythonImpl::GetShortHelpForCommandObject( 29510b57cec5SDimitry Andric StructuredData::GenericSP cmd_obj_sp, std::string &dest) { 29520b57cec5SDimitry Andric dest.clear(); 29530b57cec5SDimitry Andric 29540b57cec5SDimitry Andric Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock); 29550b57cec5SDimitry Andric 29560b57cec5SDimitry Andric if (!cmd_obj_sp) 29570b57cec5SDimitry Andric return false; 29580b57cec5SDimitry Andric 29590b57cec5SDimitry Andric PythonObject implementor(PyRefType::Borrowed, 29600b57cec5SDimitry Andric (PyObject *)cmd_obj_sp->GetValue()); 29610b57cec5SDimitry Andric 29620b57cec5SDimitry Andric if (!implementor.IsAllocated()) 29630b57cec5SDimitry Andric return false; 29640b57cec5SDimitry Andric 2965bdd1243dSDimitry Andric llvm::Expected<PythonObject> expected_py_return = 2966bdd1243dSDimitry Andric implementor.CallMethod("get_short_help"); 29670b57cec5SDimitry Andric 2968bdd1243dSDimitry Andric if (!expected_py_return) { 2969bdd1243dSDimitry Andric llvm::consumeError(expected_py_return.takeError()); 29700b57cec5SDimitry Andric return false; 29710b57cec5SDimitry Andric } 29720b57cec5SDimitry Andric 2973bdd1243dSDimitry Andric PythonObject py_return = std::move(expected_py_return.get()); 29740b57cec5SDimitry Andric 29750b57cec5SDimitry Andric if (py_return.IsAllocated() && PythonString::Check(py_return.get())) { 29760b57cec5SDimitry Andric PythonString py_string(PyRefType::Borrowed, py_return.get()); 29770b57cec5SDimitry Andric llvm::StringRef return_data(py_string.GetString()); 29780b57cec5SDimitry Andric dest.assign(return_data.data(), return_data.size()); 29795ffd83dbSDimitry Andric return true; 29800b57cec5SDimitry Andric } 29815ffd83dbSDimitry Andric 29825ffd83dbSDimitry Andric return false; 29830b57cec5SDimitry Andric } 29840b57cec5SDimitry Andric 29850b57cec5SDimitry Andric uint32_t ScriptInterpreterPythonImpl::GetFlagsForCommandObject( 29860b57cec5SDimitry Andric StructuredData::GenericSP cmd_obj_sp) { 29870b57cec5SDimitry Andric uint32_t result = 0; 29880b57cec5SDimitry Andric 29890b57cec5SDimitry Andric Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock); 29900b57cec5SDimitry Andric 29910b57cec5SDimitry Andric static char callee_name[] = "get_flags"; 29920b57cec5SDimitry Andric 29930b57cec5SDimitry Andric if (!cmd_obj_sp) 29940b57cec5SDimitry Andric return result; 29950b57cec5SDimitry Andric 29960b57cec5SDimitry Andric PythonObject implementor(PyRefType::Borrowed, 29970b57cec5SDimitry Andric (PyObject *)cmd_obj_sp->GetValue()); 29980b57cec5SDimitry Andric 29990b57cec5SDimitry Andric if (!implementor.IsAllocated()) 30000b57cec5SDimitry Andric return result; 30010b57cec5SDimitry Andric 30020b57cec5SDimitry Andric PythonObject pmeth(PyRefType::Owned, 30030b57cec5SDimitry Andric PyObject_GetAttrString(implementor.get(), callee_name)); 30040b57cec5SDimitry Andric 30050b57cec5SDimitry Andric if (PyErr_Occurred()) 30060b57cec5SDimitry Andric PyErr_Clear(); 30070b57cec5SDimitry Andric 30080b57cec5SDimitry Andric if (!pmeth.IsAllocated()) 30090b57cec5SDimitry Andric return result; 30100b57cec5SDimitry Andric 30110b57cec5SDimitry Andric if (PyCallable_Check(pmeth.get()) == 0) { 30120b57cec5SDimitry Andric if (PyErr_Occurred()) 30130b57cec5SDimitry Andric PyErr_Clear(); 30140b57cec5SDimitry Andric return result; 30150b57cec5SDimitry Andric } 30160b57cec5SDimitry Andric 30170b57cec5SDimitry Andric if (PyErr_Occurred()) 30180b57cec5SDimitry Andric PyErr_Clear(); 30190b57cec5SDimitry Andric 30205ffd83dbSDimitry Andric long long py_return = unwrapOrSetPythonException( 30215ffd83dbSDimitry Andric As<long long>(implementor.CallMethod(callee_name))); 30220b57cec5SDimitry Andric 30230b57cec5SDimitry Andric // if it fails, print the error but otherwise go on 30240b57cec5SDimitry Andric if (PyErr_Occurred()) { 30250b57cec5SDimitry Andric PyErr_Print(); 30260b57cec5SDimitry Andric PyErr_Clear(); 30275ffd83dbSDimitry Andric } else { 30285ffd83dbSDimitry Andric result = py_return; 30290b57cec5SDimitry Andric } 30300b57cec5SDimitry Andric 30310b57cec5SDimitry Andric return result; 30320b57cec5SDimitry Andric } 30330b57cec5SDimitry Andric 30340b57cec5SDimitry Andric bool ScriptInterpreterPythonImpl::GetLongHelpForCommandObject( 30350b57cec5SDimitry Andric StructuredData::GenericSP cmd_obj_sp, std::string &dest) { 30360b57cec5SDimitry Andric dest.clear(); 30370b57cec5SDimitry Andric 30380b57cec5SDimitry Andric Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock); 30390b57cec5SDimitry Andric 30400b57cec5SDimitry Andric if (!cmd_obj_sp) 30410b57cec5SDimitry Andric return false; 30420b57cec5SDimitry Andric 30430b57cec5SDimitry Andric PythonObject implementor(PyRefType::Borrowed, 30440b57cec5SDimitry Andric (PyObject *)cmd_obj_sp->GetValue()); 30450b57cec5SDimitry Andric 30460b57cec5SDimitry Andric if (!implementor.IsAllocated()) 30470b57cec5SDimitry Andric return false; 30480b57cec5SDimitry Andric 3049bdd1243dSDimitry Andric llvm::Expected<PythonObject> expected_py_return = 3050bdd1243dSDimitry Andric implementor.CallMethod("get_long_help"); 30510b57cec5SDimitry Andric 3052bdd1243dSDimitry Andric if (!expected_py_return) { 3053bdd1243dSDimitry Andric llvm::consumeError(expected_py_return.takeError()); 30540b57cec5SDimitry Andric return false; 30550b57cec5SDimitry Andric } 30560b57cec5SDimitry Andric 3057bdd1243dSDimitry Andric PythonObject py_return = std::move(expected_py_return.get()); 30580b57cec5SDimitry Andric 3059bdd1243dSDimitry Andric bool got_string = false; 30600b57cec5SDimitry Andric if (py_return.IsAllocated() && PythonString::Check(py_return.get())) { 30610b57cec5SDimitry Andric PythonString str(PyRefType::Borrowed, py_return.get()); 30620b57cec5SDimitry Andric llvm::StringRef str_data(str.GetString()); 30630b57cec5SDimitry Andric dest.assign(str_data.data(), str_data.size()); 30640b57cec5SDimitry Andric got_string = true; 30650b57cec5SDimitry Andric } 30660b57cec5SDimitry Andric 30670b57cec5SDimitry Andric return got_string; 30680b57cec5SDimitry Andric } 30690b57cec5SDimitry Andric 30700b57cec5SDimitry Andric std::unique_ptr<ScriptInterpreterLocker> 30710b57cec5SDimitry Andric ScriptInterpreterPythonImpl::AcquireInterpreterLock() { 30720b57cec5SDimitry Andric std::unique_ptr<ScriptInterpreterLocker> py_lock(new Locker( 30730b57cec5SDimitry Andric this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN, 30740b57cec5SDimitry Andric Locker::FreeLock | Locker::TearDownSession)); 30750b57cec5SDimitry Andric return py_lock; 30760b57cec5SDimitry Andric } 30770b57cec5SDimitry Andric 307804eeddc0SDimitry Andric void ScriptInterpreterPythonImpl::Initialize() { 3079e8d8bef9SDimitry Andric LLDB_SCOPED_TIMER(); 30800b57cec5SDimitry Andric 30810b57cec5SDimitry Andric // RAII-based initialization which correctly handles multiple-initialization, 30820b57cec5SDimitry Andric // version- specific differences among Python 2 and Python 3, and saving and 30830b57cec5SDimitry Andric // restoring various other pieces of state that can get mucked with during 30840b57cec5SDimitry Andric // initialization. 30850b57cec5SDimitry Andric InitializePythonRAII initialize_guard; 30860b57cec5SDimitry Andric 30870b57cec5SDimitry Andric LLDBSwigPyInit(); 30880b57cec5SDimitry Andric 30890b57cec5SDimitry Andric // Update the path python uses to search for modules to include the current 30900b57cec5SDimitry Andric // directory. 30910b57cec5SDimitry Andric 30920b57cec5SDimitry Andric PyRun_SimpleString("import sys"); 30930b57cec5SDimitry Andric AddToSysPath(AddLocation::End, "."); 30940b57cec5SDimitry Andric 30950b57cec5SDimitry Andric // Don't denormalize paths when calling file_spec.GetPath(). On platforms 30960b57cec5SDimitry Andric // that use a backslash as the path separator, this will result in executing 30970b57cec5SDimitry Andric // python code containing paths with unescaped backslashes. But Python also 30980b57cec5SDimitry Andric // accepts forward slashes, so to make life easier we just use that. 30990b57cec5SDimitry Andric if (FileSpec file_spec = GetPythonDir()) 31000b57cec5SDimitry Andric AddToSysPath(AddLocation::Beginning, file_spec.GetPath(false)); 31010b57cec5SDimitry Andric if (FileSpec file_spec = HostInfo::GetShlibDir()) 31020b57cec5SDimitry Andric AddToSysPath(AddLocation::Beginning, file_spec.GetPath(false)); 31030b57cec5SDimitry Andric 31040b57cec5SDimitry Andric PyRun_SimpleString("sys.dont_write_bytecode = 1; import " 31050b57cec5SDimitry Andric "lldb.embedded_interpreter; from " 31060b57cec5SDimitry Andric "lldb.embedded_interpreter import run_python_interpreter; " 31070b57cec5SDimitry Andric "from lldb.embedded_interpreter import run_one_line"); 310804eeddc0SDimitry Andric 310904eeddc0SDimitry Andric #if LLDB_USE_PYTHON_SET_INTERRUPT 311004eeddc0SDimitry Andric // Python will not just overwrite its internal SIGINT handler but also the 311104eeddc0SDimitry Andric // one from the process. Backup the current SIGINT handler to prevent that 311204eeddc0SDimitry Andric // Python deletes it. 311304eeddc0SDimitry Andric RestoreSignalHandlerScope save_sigint(SIGINT); 311404eeddc0SDimitry Andric 311504eeddc0SDimitry Andric // Setup a default SIGINT signal handler that works the same way as the 311604eeddc0SDimitry Andric // normal Python REPL signal handler which raises a KeyboardInterrupt. 311704eeddc0SDimitry Andric // Also make sure to not pollute the user's REPL with the signal module nor 311804eeddc0SDimitry Andric // our utility function. 311904eeddc0SDimitry Andric PyRun_SimpleString("def lldb_setup_sigint_handler():\n" 312004eeddc0SDimitry Andric " import signal;\n" 312104eeddc0SDimitry Andric " def signal_handler(sig, frame):\n" 312204eeddc0SDimitry Andric " raise KeyboardInterrupt()\n" 312304eeddc0SDimitry Andric " signal.signal(signal.SIGINT, signal_handler);\n" 312404eeddc0SDimitry Andric "lldb_setup_sigint_handler();\n" 312504eeddc0SDimitry Andric "del lldb_setup_sigint_handler\n"); 312604eeddc0SDimitry Andric #endif 31270b57cec5SDimitry Andric } 31280b57cec5SDimitry Andric 31290b57cec5SDimitry Andric void ScriptInterpreterPythonImpl::AddToSysPath(AddLocation location, 31300b57cec5SDimitry Andric std::string path) { 31310b57cec5SDimitry Andric std::string path_copy; 31320b57cec5SDimitry Andric 31330b57cec5SDimitry Andric std::string statement; 31340b57cec5SDimitry Andric if (location == AddLocation::Beginning) { 31350b57cec5SDimitry Andric statement.assign("sys.path.insert(0,\""); 31360b57cec5SDimitry Andric statement.append(path); 31370b57cec5SDimitry Andric statement.append("\")"); 31380b57cec5SDimitry Andric } else { 31390b57cec5SDimitry Andric statement.assign("sys.path.append(\""); 31400b57cec5SDimitry Andric statement.append(path); 31410b57cec5SDimitry Andric statement.append("\")"); 31420b57cec5SDimitry Andric } 31430b57cec5SDimitry Andric PyRun_SimpleString(statement.c_str()); 31440b57cec5SDimitry Andric } 31450b57cec5SDimitry Andric 31460b57cec5SDimitry Andric // We are intentionally NOT calling Py_Finalize here (this would be the logical 31470b57cec5SDimitry Andric // place to call it). Calling Py_Finalize here causes test suite runs to seg 31480b57cec5SDimitry Andric // fault: The test suite runs in Python. It registers SBDebugger::Terminate to 31490b57cec5SDimitry Andric // be called 'at_exit'. When the test suite Python harness finishes up, it 31500b57cec5SDimitry Andric // calls Py_Finalize, which calls all the 'at_exit' registered functions. 31510b57cec5SDimitry Andric // SBDebugger::Terminate calls Debugger::Terminate, which calls lldb::Terminate, 31520b57cec5SDimitry Andric // which calls ScriptInterpreter::Terminate, which calls 31530b57cec5SDimitry Andric // ScriptInterpreterPythonImpl::Terminate. So if we call Py_Finalize here, we 31540b57cec5SDimitry Andric // end up with Py_Finalize being called from within Py_Finalize, which results 31550b57cec5SDimitry Andric // in a seg fault. Since this function only gets called when lldb is shutting 31560b57cec5SDimitry Andric // down and going away anyway, the fact that we don't actually call Py_Finalize 31570b57cec5SDimitry Andric // should not cause any problems (everything should shut down/go away anyway 31580b57cec5SDimitry Andric // when the process exits). 31590b57cec5SDimitry Andric // 31600b57cec5SDimitry Andric // void ScriptInterpreterPythonImpl::Terminate() { Py_Finalize (); } 31610b57cec5SDimitry Andric 3162480093f4SDimitry Andric #endif 3163