1dda28197Spatrick //===-- ScriptInterpreterPython.cpp ---------------------------------------===// 2061da546Spatrick // 3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information. 5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6061da546Spatrick // 7061da546Spatrick //===----------------------------------------------------------------------===// 8061da546Spatrick 9061da546Spatrick #include "lldb/Host/Config.h" 10*be691f3bSpatrick #include "lldb/lldb-enumerations.h" 11061da546Spatrick 12061da546Spatrick #if LLDB_ENABLE_PYTHON 13061da546Spatrick 14061da546Spatrick // LLDB Python header must be included first 15061da546Spatrick #include "lldb-python.h" 16061da546Spatrick 17061da546Spatrick #include "PythonDataObjects.h" 18061da546Spatrick #include "PythonReadline.h" 19*be691f3bSpatrick #include "SWIGPythonBridge.h" 20061da546Spatrick #include "ScriptInterpreterPythonImpl.h" 21*be691f3bSpatrick #include "ScriptedProcessPythonInterface.h" 22*be691f3bSpatrick 23*be691f3bSpatrick #include "lldb/API/SBError.h" 24061da546Spatrick #include "lldb/API/SBFrame.h" 25061da546Spatrick #include "lldb/API/SBValue.h" 26061da546Spatrick #include "lldb/Breakpoint/StoppointCallbackContext.h" 27061da546Spatrick #include "lldb/Breakpoint/WatchpointOptions.h" 28061da546Spatrick #include "lldb/Core/Communication.h" 29061da546Spatrick #include "lldb/Core/Debugger.h" 30061da546Spatrick #include "lldb/Core/PluginManager.h" 31061da546Spatrick #include "lldb/Core/ValueObject.h" 32061da546Spatrick #include "lldb/DataFormatters/TypeSummary.h" 33061da546Spatrick #include "lldb/Host/FileSystem.h" 34061da546Spatrick #include "lldb/Host/HostInfo.h" 35061da546Spatrick #include "lldb/Host/Pipe.h" 36061da546Spatrick #include "lldb/Interpreter/CommandInterpreter.h" 37061da546Spatrick #include "lldb/Interpreter/CommandReturnObject.h" 38061da546Spatrick #include "lldb/Target/Thread.h" 39061da546Spatrick #include "lldb/Target/ThreadPlan.h" 40*be691f3bSpatrick #include "lldb/Utility/ReproducerInstrumentation.h" 41061da546Spatrick #include "lldb/Utility/Timer.h" 42061da546Spatrick #include "llvm/ADT/STLExtras.h" 43061da546Spatrick #include "llvm/ADT/StringRef.h" 44dda28197Spatrick #include "llvm/Support/Error.h" 45061da546Spatrick #include "llvm/Support/FileSystem.h" 46061da546Spatrick #include "llvm/Support/FormatAdapters.h" 47061da546Spatrick 48*be691f3bSpatrick #include <cstdio> 49*be691f3bSpatrick #include <cstdlib> 50061da546Spatrick #include <memory> 51061da546Spatrick #include <mutex> 52061da546Spatrick #include <string> 53061da546Spatrick 54061da546Spatrick using namespace lldb; 55061da546Spatrick using namespace lldb_private; 56061da546Spatrick using namespace lldb_private::python; 57061da546Spatrick using llvm::Expected; 58061da546Spatrick 59dda28197Spatrick LLDB_PLUGIN_DEFINE(ScriptInterpreterPython) 60dda28197Spatrick 61061da546Spatrick // Defined in the SWIG source file 62061da546Spatrick #if PY_MAJOR_VERSION >= 3 63061da546Spatrick extern "C" PyObject *PyInit__lldb(void); 64061da546Spatrick 65061da546Spatrick #define LLDBSwigPyInit PyInit__lldb 66061da546Spatrick 67061da546Spatrick #else 68061da546Spatrick extern "C" void init_lldb(void); 69061da546Spatrick 70061da546Spatrick #define LLDBSwigPyInit init_lldb 71061da546Spatrick #endif 72061da546Spatrick 73061da546Spatrick // These prototypes are the Pythonic implementations of the required callbacks. 74061da546Spatrick // Although these are scripting-language specific, their definition depends on 75061da546Spatrick // the public API. 76061da546Spatrick 77061da546Spatrick #pragma clang diagnostic push 78061da546Spatrick #pragma clang diagnostic ignored "-Wreturn-type-c-linkage" 79061da546Spatrick 80061da546Spatrick // Disable warning C4190: 'LLDBSwigPythonBreakpointCallbackFunction' has 81061da546Spatrick // C-linkage specified, but returns UDT 'llvm::Expected<bool>' which is 82061da546Spatrick // incompatible with C 83061da546Spatrick #if _MSC_VER 84061da546Spatrick #pragma warning (push) 85061da546Spatrick #pragma warning (disable : 4190) 86061da546Spatrick #endif 87061da546Spatrick 88061da546Spatrick extern "C" llvm::Expected<bool> LLDBSwigPythonBreakpointCallbackFunction( 89061da546Spatrick const char *python_function_name, const char *session_dictionary_name, 90061da546Spatrick const lldb::StackFrameSP &sb_frame, 91061da546Spatrick const lldb::BreakpointLocationSP &sb_bp_loc, StructuredDataImpl *args_impl); 92061da546Spatrick 93061da546Spatrick #if _MSC_VER 94061da546Spatrick #pragma warning (pop) 95061da546Spatrick #endif 96061da546Spatrick 97061da546Spatrick #pragma clang diagnostic pop 98061da546Spatrick 99061da546Spatrick extern "C" bool LLDBSwigPythonWatchpointCallbackFunction( 100061da546Spatrick const char *python_function_name, const char *session_dictionary_name, 101061da546Spatrick const lldb::StackFrameSP &sb_frame, const lldb::WatchpointSP &sb_wp); 102061da546Spatrick 103061da546Spatrick extern "C" bool LLDBSwigPythonCallTypeScript( 104061da546Spatrick const char *python_function_name, void *session_dictionary, 105061da546Spatrick const lldb::ValueObjectSP &valobj_sp, void **pyfunct_wrapper, 106061da546Spatrick const lldb::TypeSummaryOptionsSP &options_sp, std::string &retval); 107061da546Spatrick 108061da546Spatrick extern "C" void * 109061da546Spatrick LLDBSwigPythonCreateSyntheticProvider(const char *python_class_name, 110061da546Spatrick const char *session_dictionary_name, 111061da546Spatrick const lldb::ValueObjectSP &valobj_sp); 112061da546Spatrick 113061da546Spatrick extern "C" void * 114061da546Spatrick LLDBSwigPythonCreateCommandObject(const char *python_class_name, 115061da546Spatrick const char *session_dictionary_name, 116061da546Spatrick const lldb::DebuggerSP debugger_sp); 117061da546Spatrick 118061da546Spatrick extern "C" void *LLDBSwigPythonCreateScriptedThreadPlan( 119061da546Spatrick const char *python_class_name, const char *session_dictionary_name, 120061da546Spatrick StructuredDataImpl *args_data, 121061da546Spatrick std::string &error_string, 122061da546Spatrick const lldb::ThreadPlanSP &thread_plan_sp); 123061da546Spatrick 124061da546Spatrick extern "C" bool LLDBSWIGPythonCallThreadPlan(void *implementor, 125061da546Spatrick const char *method_name, 126061da546Spatrick Event *event_sp, bool &got_error); 127061da546Spatrick 128061da546Spatrick extern "C" void *LLDBSwigPythonCreateScriptedBreakpointResolver( 129061da546Spatrick const char *python_class_name, const char *session_dictionary_name, 130061da546Spatrick lldb_private::StructuredDataImpl *args, lldb::BreakpointSP &bkpt_sp); 131061da546Spatrick 132061da546Spatrick extern "C" unsigned int 133061da546Spatrick LLDBSwigPythonCallBreakpointResolver(void *implementor, const char *method_name, 134061da546Spatrick lldb_private::SymbolContext *sym_ctx); 135061da546Spatrick 136*be691f3bSpatrick extern "C" void *LLDBSwigPythonCreateScriptedStopHook( 137*be691f3bSpatrick TargetSP target_sp, const char *python_class_name, 138*be691f3bSpatrick const char *session_dictionary_name, lldb_private::StructuredDataImpl *args, 139*be691f3bSpatrick lldb_private::Status &error); 140*be691f3bSpatrick 141*be691f3bSpatrick extern "C" bool 142*be691f3bSpatrick LLDBSwigPythonStopHookCallHandleStop(void *implementor, 143*be691f3bSpatrick lldb::ExecutionContextRefSP exc_ctx, 144*be691f3bSpatrick lldb::StreamSP stream); 145*be691f3bSpatrick 146061da546Spatrick extern "C" size_t LLDBSwigPython_CalculateNumChildren(void *implementor, 147061da546Spatrick uint32_t max); 148061da546Spatrick 149061da546Spatrick extern "C" void *LLDBSwigPython_GetChildAtIndex(void *implementor, 150061da546Spatrick uint32_t idx); 151061da546Spatrick 152061da546Spatrick extern "C" int LLDBSwigPython_GetIndexOfChildWithName(void *implementor, 153061da546Spatrick const char *child_name); 154061da546Spatrick 155061da546Spatrick extern lldb::ValueObjectSP 156061da546Spatrick LLDBSWIGPython_GetValueObjectSPFromSBValue(void *data); 157061da546Spatrick 158061da546Spatrick extern "C" bool LLDBSwigPython_UpdateSynthProviderInstance(void *implementor); 159061da546Spatrick 160061da546Spatrick extern "C" bool 161061da546Spatrick LLDBSwigPython_MightHaveChildrenSynthProviderInstance(void *implementor); 162061da546Spatrick 163061da546Spatrick extern "C" void * 164061da546Spatrick LLDBSwigPython_GetValueSynthProviderInstance(void *implementor); 165061da546Spatrick 166061da546Spatrick extern "C" bool 167061da546Spatrick LLDBSwigPythonCallCommand(const char *python_function_name, 168061da546Spatrick const char *session_dictionary_name, 169061da546Spatrick lldb::DebuggerSP &debugger, const char *args, 170061da546Spatrick lldb_private::CommandReturnObject &cmd_retobj, 171061da546Spatrick lldb::ExecutionContextRefSP exe_ctx_ref_sp); 172061da546Spatrick 173061da546Spatrick extern "C" bool 174061da546Spatrick LLDBSwigPythonCallCommandObject(void *implementor, lldb::DebuggerSP &debugger, 175061da546Spatrick const char *args, 176061da546Spatrick lldb_private::CommandReturnObject &cmd_retobj, 177061da546Spatrick lldb::ExecutionContextRefSP exe_ctx_ref_sp); 178061da546Spatrick 179061da546Spatrick extern "C" bool 180061da546Spatrick LLDBSwigPythonCallModuleInit(const char *python_module_name, 181061da546Spatrick const char *session_dictionary_name, 182061da546Spatrick lldb::DebuggerSP &debugger); 183061da546Spatrick 184061da546Spatrick extern "C" void * 185061da546Spatrick LLDBSWIGPythonCreateOSPlugin(const char *python_class_name, 186061da546Spatrick const char *session_dictionary_name, 187061da546Spatrick const lldb::ProcessSP &process_sp); 188061da546Spatrick 189061da546Spatrick extern "C" void * 190061da546Spatrick LLDBSWIGPython_CreateFrameRecognizer(const char *python_class_name, 191061da546Spatrick const char *session_dictionary_name); 192061da546Spatrick 193061da546Spatrick extern "C" void * 194061da546Spatrick LLDBSwigPython_GetRecognizedArguments(void *implementor, 195061da546Spatrick const lldb::StackFrameSP &frame_sp); 196061da546Spatrick 197061da546Spatrick extern "C" bool LLDBSWIGPythonRunScriptKeywordProcess( 198061da546Spatrick const char *python_function_name, const char *session_dictionary_name, 199061da546Spatrick lldb::ProcessSP &process, std::string &output); 200061da546Spatrick 201061da546Spatrick extern "C" bool LLDBSWIGPythonRunScriptKeywordThread( 202061da546Spatrick const char *python_function_name, const char *session_dictionary_name, 203061da546Spatrick lldb::ThreadSP &thread, std::string &output); 204061da546Spatrick 205061da546Spatrick extern "C" bool LLDBSWIGPythonRunScriptKeywordTarget( 206061da546Spatrick const char *python_function_name, const char *session_dictionary_name, 207061da546Spatrick lldb::TargetSP &target, std::string &output); 208061da546Spatrick 209061da546Spatrick extern "C" bool LLDBSWIGPythonRunScriptKeywordFrame( 210061da546Spatrick const char *python_function_name, const char *session_dictionary_name, 211061da546Spatrick lldb::StackFrameSP &frame, std::string &output); 212061da546Spatrick 213061da546Spatrick extern "C" bool LLDBSWIGPythonRunScriptKeywordValue( 214061da546Spatrick const char *python_function_name, const char *session_dictionary_name, 215061da546Spatrick lldb::ValueObjectSP &value, std::string &output); 216061da546Spatrick 217061da546Spatrick extern "C" void * 218061da546Spatrick LLDBSWIGPython_GetDynamicSetting(void *module, const char *setting, 219061da546Spatrick const lldb::TargetSP &target_sp); 220061da546Spatrick 221*be691f3bSpatrick static ScriptInterpreterPythonImpl *GetPythonInterpreter(Debugger &debugger) { 222*be691f3bSpatrick ScriptInterpreter *script_interpreter = 223*be691f3bSpatrick debugger.GetScriptInterpreter(true, lldb::eScriptLanguagePython); 224*be691f3bSpatrick return static_cast<ScriptInterpreterPythonImpl *>(script_interpreter); 225*be691f3bSpatrick } 226*be691f3bSpatrick 227061da546Spatrick static bool g_initialized = false; 228061da546Spatrick 229061da546Spatrick namespace { 230061da546Spatrick 231061da546Spatrick // Initializing Python is not a straightforward process. We cannot control 232061da546Spatrick // what external code may have done before getting to this point in LLDB, 233061da546Spatrick // including potentially having already initialized Python, so we need to do a 234061da546Spatrick // lot of work to ensure that the existing state of the system is maintained 235061da546Spatrick // across our initialization. We do this by using an RAII pattern where we 236061da546Spatrick // save off initial state at the beginning, and restore it at the end 237061da546Spatrick struct InitializePythonRAII { 238061da546Spatrick public: 239*be691f3bSpatrick InitializePythonRAII() { 240061da546Spatrick InitializePythonHome(); 241061da546Spatrick 242061da546Spatrick #ifdef LLDB_USE_LIBEDIT_READLINE_COMPAT_MODULE 243061da546Spatrick // Python's readline is incompatible with libedit being linked into lldb. 244061da546Spatrick // Provide a patched version local to the embedded interpreter. 245061da546Spatrick bool ReadlinePatched = false; 246061da546Spatrick for (auto *p = PyImport_Inittab; p->name != NULL; p++) { 247061da546Spatrick if (strcmp(p->name, "readline") == 0) { 248061da546Spatrick p->initfunc = initlldb_readline; 249061da546Spatrick break; 250061da546Spatrick } 251061da546Spatrick } 252061da546Spatrick if (!ReadlinePatched) { 253061da546Spatrick PyImport_AppendInittab("readline", initlldb_readline); 254061da546Spatrick ReadlinePatched = true; 255061da546Spatrick } 256061da546Spatrick #endif 257061da546Spatrick 258061da546Spatrick // Register _lldb as a built-in module. 259061da546Spatrick PyImport_AppendInittab("_lldb", LLDBSwigPyInit); 260061da546Spatrick 261061da546Spatrick // Python < 3.2 and Python >= 3.2 reversed the ordering requirements for 262061da546Spatrick // calling `Py_Initialize` and `PyEval_InitThreads`. < 3.2 requires that you 263061da546Spatrick // call `PyEval_InitThreads` first, and >= 3.2 requires that you call it last. 264061da546Spatrick #if (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 2) || (PY_MAJOR_VERSION > 3) 265061da546Spatrick Py_InitializeEx(0); 266061da546Spatrick InitializeThreadsPrivate(); 267061da546Spatrick #else 268061da546Spatrick InitializeThreadsPrivate(); 269061da546Spatrick Py_InitializeEx(0); 270061da546Spatrick #endif 271061da546Spatrick } 272061da546Spatrick 273061da546Spatrick ~InitializePythonRAII() { 274061da546Spatrick if (m_was_already_initialized) { 275061da546Spatrick Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SCRIPT)); 276061da546Spatrick LLDB_LOGV(log, "Releasing PyGILState. Returning to state = {0}locked", 277061da546Spatrick m_gil_state == PyGILState_UNLOCKED ? "un" : ""); 278061da546Spatrick PyGILState_Release(m_gil_state); 279061da546Spatrick } else { 280061da546Spatrick // We initialized the threads in this function, just unlock the GIL. 281061da546Spatrick PyEval_SaveThread(); 282061da546Spatrick } 283061da546Spatrick } 284061da546Spatrick 285061da546Spatrick private: 286061da546Spatrick void InitializePythonHome() { 287dda28197Spatrick #if LLDB_EMBED_PYTHON_HOME 288dda28197Spatrick #if PY_MAJOR_VERSION >= 3 289dda28197Spatrick typedef wchar_t* str_type; 290dda28197Spatrick #else 291dda28197Spatrick typedef char* str_type; 292dda28197Spatrick #endif 293dda28197Spatrick static str_type g_python_home = []() -> str_type { 294dda28197Spatrick const char *lldb_python_home = LLDB_PYTHON_HOME; 295dda28197Spatrick const char *absolute_python_home = nullptr; 296dda28197Spatrick llvm::SmallString<64> path; 297dda28197Spatrick if (llvm::sys::path::is_absolute(lldb_python_home)) { 298dda28197Spatrick absolute_python_home = lldb_python_home; 299dda28197Spatrick } else { 300dda28197Spatrick FileSpec spec = HostInfo::GetShlibDir(); 301dda28197Spatrick if (!spec) 302dda28197Spatrick return nullptr; 303dda28197Spatrick spec.GetPath(path); 304dda28197Spatrick llvm::sys::path::append(path, lldb_python_home); 305dda28197Spatrick absolute_python_home = path.c_str(); 306dda28197Spatrick } 307061da546Spatrick #if PY_MAJOR_VERSION >= 3 308061da546Spatrick size_t size = 0; 309dda28197Spatrick return Py_DecodeLocale(absolute_python_home, &size); 310061da546Spatrick #else 311dda28197Spatrick return strdup(absolute_python_home); 312061da546Spatrick #endif 313dda28197Spatrick }(); 314dda28197Spatrick if (g_python_home != nullptr) { 315061da546Spatrick Py_SetPythonHome(g_python_home); 316dda28197Spatrick } 317061da546Spatrick #else 318061da546Spatrick #if defined(__APPLE__) && PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION == 7 319061da546Spatrick // For Darwin, the only Python version supported is the one shipped in the 320061da546Spatrick // OS OS and linked with lldb. Other installation of Python may have higher 321061da546Spatrick // priorities in the path, overriding PYTHONHOME and causing 322061da546Spatrick // problems/incompatibilities. In order to avoid confusion, always hardcode 323061da546Spatrick // the PythonHome to be right, as it's not going to change. 324061da546Spatrick static char path[] = 325061da546Spatrick "/System/Library/Frameworks/Python.framework/Versions/2.7"; 326061da546Spatrick Py_SetPythonHome(path); 327061da546Spatrick #endif 328061da546Spatrick #endif 329061da546Spatrick } 330061da546Spatrick 331061da546Spatrick void InitializeThreadsPrivate() { 332061da546Spatrick // Since Python 3.7 `Py_Initialize` calls `PyEval_InitThreads` inside itself, 333061da546Spatrick // so there is no way to determine whether the embedded interpreter 334061da546Spatrick // was already initialized by some external code. `PyEval_ThreadsInitialized` 335061da546Spatrick // would always return `true` and `PyGILState_Ensure/Release` flow would be 336061da546Spatrick // executed instead of unlocking GIL with `PyEval_SaveThread`. When 337061da546Spatrick // an another thread calls `PyGILState_Ensure` it would get stuck in deadlock. 338061da546Spatrick #if (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 7) || (PY_MAJOR_VERSION > 3) 339061da546Spatrick // The only case we should go further and acquire the GIL: it is unlocked. 340061da546Spatrick if (PyGILState_Check()) 341061da546Spatrick return; 342061da546Spatrick #endif 343061da546Spatrick 344061da546Spatrick if (PyEval_ThreadsInitialized()) { 345061da546Spatrick Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SCRIPT)); 346061da546Spatrick 347061da546Spatrick m_was_already_initialized = true; 348061da546Spatrick m_gil_state = PyGILState_Ensure(); 349061da546Spatrick LLDB_LOGV(log, "Ensured PyGILState. Previous state = {0}locked\n", 350061da546Spatrick m_gil_state == PyGILState_UNLOCKED ? "un" : ""); 351061da546Spatrick return; 352061da546Spatrick } 353061da546Spatrick 354061da546Spatrick // InitThreads acquires the GIL if it hasn't been called before. 355061da546Spatrick PyEval_InitThreads(); 356061da546Spatrick } 357061da546Spatrick 358061da546Spatrick TerminalState m_stdin_tty_state; 359*be691f3bSpatrick PyGILState_STATE m_gil_state = PyGILState_UNLOCKED; 360*be691f3bSpatrick bool m_was_already_initialized = false; 361061da546Spatrick }; 362061da546Spatrick } // namespace 363061da546Spatrick 364061da546Spatrick void ScriptInterpreterPython::ComputePythonDirForApple( 365061da546Spatrick llvm::SmallVectorImpl<char> &path) { 366061da546Spatrick auto style = llvm::sys::path::Style::posix; 367061da546Spatrick 368061da546Spatrick llvm::StringRef path_ref(path.begin(), path.size()); 369061da546Spatrick auto rbegin = llvm::sys::path::rbegin(path_ref, style); 370061da546Spatrick auto rend = llvm::sys::path::rend(path_ref); 371061da546Spatrick auto framework = std::find(rbegin, rend, "LLDB.framework"); 372061da546Spatrick if (framework == rend) { 373061da546Spatrick ComputePythonDir(path); 374061da546Spatrick return; 375061da546Spatrick } 376061da546Spatrick path.resize(framework - rend); 377061da546Spatrick llvm::sys::path::append(path, style, "LLDB.framework", "Resources", "Python"); 378061da546Spatrick } 379061da546Spatrick 380061da546Spatrick void ScriptInterpreterPython::ComputePythonDir( 381061da546Spatrick llvm::SmallVectorImpl<char> &path) { 382061da546Spatrick // Build the path by backing out of the lib dir, then building with whatever 383061da546Spatrick // the real python interpreter uses. (e.g. lib for most, lib64 on RHEL 384061da546Spatrick // x86_64, or bin on Windows). 385061da546Spatrick llvm::sys::path::remove_filename(path); 386061da546Spatrick llvm::sys::path::append(path, LLDB_PYTHON_RELATIVE_LIBDIR); 387061da546Spatrick 388061da546Spatrick #if defined(_WIN32) 389061da546Spatrick // This will be injected directly through FileSpec.GetDirectory().SetString(), 390061da546Spatrick // so we need to normalize manually. 391061da546Spatrick std::replace(path.begin(), path.end(), '\\', '/'); 392061da546Spatrick #endif 393061da546Spatrick } 394061da546Spatrick 395061da546Spatrick FileSpec ScriptInterpreterPython::GetPythonDir() { 396061da546Spatrick static FileSpec g_spec = []() { 397061da546Spatrick FileSpec spec = HostInfo::GetShlibDir(); 398061da546Spatrick if (!spec) 399061da546Spatrick return FileSpec(); 400061da546Spatrick llvm::SmallString<64> path; 401061da546Spatrick spec.GetPath(path); 402061da546Spatrick 403061da546Spatrick #if defined(__APPLE__) 404061da546Spatrick ComputePythonDirForApple(path); 405061da546Spatrick #else 406061da546Spatrick ComputePythonDir(path); 407061da546Spatrick #endif 408061da546Spatrick spec.GetDirectory().SetString(path); 409061da546Spatrick return spec; 410061da546Spatrick }(); 411061da546Spatrick return g_spec; 412061da546Spatrick } 413061da546Spatrick 414*be691f3bSpatrick void ScriptInterpreterPython::SharedLibraryDirectoryHelper( 415*be691f3bSpatrick FileSpec &this_file) { 416*be691f3bSpatrick // When we're loaded from python, this_file will point to the file inside the 417*be691f3bSpatrick // python package directory. Replace it with the one in the lib directory. 418*be691f3bSpatrick #ifdef _WIN32 419*be691f3bSpatrick // On windows, we need to manually back out of the python tree, and go into 420*be691f3bSpatrick // the bin directory. This is pretty much the inverse of what ComputePythonDir 421*be691f3bSpatrick // does. 422*be691f3bSpatrick if (this_file.GetFileNameExtension() == ConstString(".pyd")) { 423*be691f3bSpatrick this_file.RemoveLastPathComponent(); // _lldb.pyd or _lldb_d.pyd 424*be691f3bSpatrick this_file.RemoveLastPathComponent(); // lldb 425*be691f3bSpatrick llvm::StringRef libdir = LLDB_PYTHON_RELATIVE_LIBDIR; 426*be691f3bSpatrick for (auto it = llvm::sys::path::begin(libdir), 427*be691f3bSpatrick end = llvm::sys::path::end(libdir); 428*be691f3bSpatrick it != end; ++it) 429*be691f3bSpatrick this_file.RemoveLastPathComponent(); 430*be691f3bSpatrick this_file.AppendPathComponent("bin"); 431*be691f3bSpatrick this_file.AppendPathComponent("liblldb.dll"); 432*be691f3bSpatrick } 433*be691f3bSpatrick #else 434*be691f3bSpatrick // The python file is a symlink, so we can find the real library by resolving 435*be691f3bSpatrick // it. We can do this unconditionally. 436*be691f3bSpatrick FileSystem::Instance().ResolveSymbolicLink(this_file, this_file); 437*be691f3bSpatrick #endif 438*be691f3bSpatrick } 439*be691f3bSpatrick 440061da546Spatrick lldb_private::ConstString ScriptInterpreterPython::GetPluginNameStatic() { 441061da546Spatrick static ConstString g_name("script-python"); 442061da546Spatrick return g_name; 443061da546Spatrick } 444061da546Spatrick 445061da546Spatrick const char *ScriptInterpreterPython::GetPluginDescriptionStatic() { 446061da546Spatrick return "Embedded Python interpreter"; 447061da546Spatrick } 448061da546Spatrick 449061da546Spatrick void ScriptInterpreterPython::Initialize() { 450061da546Spatrick static llvm::once_flag g_once_flag; 451061da546Spatrick 452061da546Spatrick llvm::call_once(g_once_flag, []() { 453061da546Spatrick PluginManager::RegisterPlugin(GetPluginNameStatic(), 454061da546Spatrick GetPluginDescriptionStatic(), 455061da546Spatrick lldb::eScriptLanguagePython, 456061da546Spatrick ScriptInterpreterPythonImpl::CreateInstance); 457061da546Spatrick }); 458061da546Spatrick } 459061da546Spatrick 460061da546Spatrick void ScriptInterpreterPython::Terminate() {} 461061da546Spatrick 462061da546Spatrick ScriptInterpreterPythonImpl::Locker::Locker( 463061da546Spatrick ScriptInterpreterPythonImpl *py_interpreter, uint16_t on_entry, 464061da546Spatrick uint16_t on_leave, FileSP in, FileSP out, FileSP err) 465061da546Spatrick : ScriptInterpreterLocker(), 466061da546Spatrick m_teardown_session((on_leave & TearDownSession) == TearDownSession), 467061da546Spatrick m_python_interpreter(py_interpreter) { 468*be691f3bSpatrick repro::Recorder::PrivateThread(); 469061da546Spatrick DoAcquireLock(); 470061da546Spatrick if ((on_entry & InitSession) == InitSession) { 471061da546Spatrick if (!DoInitSession(on_entry, in, out, err)) { 472061da546Spatrick // Don't teardown the session if we didn't init it. 473061da546Spatrick m_teardown_session = false; 474061da546Spatrick } 475061da546Spatrick } 476061da546Spatrick } 477061da546Spatrick 478061da546Spatrick bool ScriptInterpreterPythonImpl::Locker::DoAcquireLock() { 479061da546Spatrick Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SCRIPT)); 480061da546Spatrick m_GILState = PyGILState_Ensure(); 481061da546Spatrick LLDB_LOGV(log, "Ensured PyGILState. Previous state = {0}locked", 482061da546Spatrick m_GILState == PyGILState_UNLOCKED ? "un" : ""); 483061da546Spatrick 484061da546Spatrick // we need to save the thread state when we first start the command because 485061da546Spatrick // we might decide to interrupt it while some action is taking place outside 486061da546Spatrick // of Python (e.g. printing to screen, waiting for the network, ...) in that 487061da546Spatrick // case, _PyThreadState_Current will be NULL - and we would be unable to set 488061da546Spatrick // the asynchronous exception - not a desirable situation 489061da546Spatrick m_python_interpreter->SetThreadState(PyThreadState_Get()); 490061da546Spatrick m_python_interpreter->IncrementLockCount(); 491061da546Spatrick return true; 492061da546Spatrick } 493061da546Spatrick 494061da546Spatrick bool ScriptInterpreterPythonImpl::Locker::DoInitSession(uint16_t on_entry_flags, 495061da546Spatrick FileSP in, FileSP out, 496061da546Spatrick FileSP err) { 497061da546Spatrick if (!m_python_interpreter) 498061da546Spatrick return false; 499061da546Spatrick return m_python_interpreter->EnterSession(on_entry_flags, in, out, err); 500061da546Spatrick } 501061da546Spatrick 502061da546Spatrick bool ScriptInterpreterPythonImpl::Locker::DoFreeLock() { 503061da546Spatrick Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SCRIPT)); 504061da546Spatrick LLDB_LOGV(log, "Releasing PyGILState. Returning to state = {0}locked", 505061da546Spatrick m_GILState == PyGILState_UNLOCKED ? "un" : ""); 506061da546Spatrick PyGILState_Release(m_GILState); 507061da546Spatrick m_python_interpreter->DecrementLockCount(); 508061da546Spatrick return true; 509061da546Spatrick } 510061da546Spatrick 511061da546Spatrick bool ScriptInterpreterPythonImpl::Locker::DoTearDownSession() { 512061da546Spatrick if (!m_python_interpreter) 513061da546Spatrick return false; 514061da546Spatrick m_python_interpreter->LeaveSession(); 515061da546Spatrick return true; 516061da546Spatrick } 517061da546Spatrick 518061da546Spatrick ScriptInterpreterPythonImpl::Locker::~Locker() { 519061da546Spatrick if (m_teardown_session) 520061da546Spatrick DoTearDownSession(); 521061da546Spatrick DoFreeLock(); 522061da546Spatrick } 523061da546Spatrick 524061da546Spatrick ScriptInterpreterPythonImpl::ScriptInterpreterPythonImpl(Debugger &debugger) 525061da546Spatrick : ScriptInterpreterPython(debugger), m_saved_stdin(), m_saved_stdout(), 526061da546Spatrick m_saved_stderr(), m_main_module(), 527061da546Spatrick m_session_dict(PyInitialValue::Invalid), 528061da546Spatrick m_sys_module_dict(PyInitialValue::Invalid), m_run_one_line_function(), 529061da546Spatrick m_run_one_line_str_global(), 530061da546Spatrick m_dictionary_name(m_debugger.GetInstanceName().AsCString()), 531061da546Spatrick m_active_io_handler(eIOHandlerNone), m_session_is_active(false), 532dda28197Spatrick m_pty_secondary_is_open(false), m_valid_session(true), m_lock_count(0), 533061da546Spatrick m_command_thread_state(nullptr) { 534061da546Spatrick InitializePrivate(); 535061da546Spatrick 536*be691f3bSpatrick m_scripted_process_interface_up = 537*be691f3bSpatrick std::make_unique<ScriptedProcessPythonInterface>(*this); 538*be691f3bSpatrick 539061da546Spatrick m_dictionary_name.append("_dict"); 540061da546Spatrick StreamString run_string; 541061da546Spatrick run_string.Printf("%s = dict()", m_dictionary_name.c_str()); 542061da546Spatrick 543061da546Spatrick Locker locker(this, Locker::AcquireLock, Locker::FreeAcquiredLock); 544061da546Spatrick PyRun_SimpleString(run_string.GetData()); 545061da546Spatrick 546061da546Spatrick run_string.Clear(); 547061da546Spatrick run_string.Printf( 548061da546Spatrick "run_one_line (%s, 'import copy, keyword, os, re, sys, uuid, lldb')", 549061da546Spatrick m_dictionary_name.c_str()); 550061da546Spatrick PyRun_SimpleString(run_string.GetData()); 551061da546Spatrick 552061da546Spatrick // Reloading modules requires a different syntax in Python 2 and Python 3. 553061da546Spatrick // This provides a consistent syntax no matter what version of Python. 554061da546Spatrick run_string.Clear(); 555061da546Spatrick run_string.Printf("run_one_line (%s, 'from six.moves import reload_module')", 556061da546Spatrick m_dictionary_name.c_str()); 557061da546Spatrick PyRun_SimpleString(run_string.GetData()); 558061da546Spatrick 559061da546Spatrick // WARNING: temporary code that loads Cocoa formatters - this should be done 560061da546Spatrick // on a per-platform basis rather than loading the whole set and letting the 561061da546Spatrick // individual formatter classes exploit APIs to check whether they can/cannot 562061da546Spatrick // do their task 563061da546Spatrick run_string.Clear(); 564061da546Spatrick run_string.Printf( 565061da546Spatrick "run_one_line (%s, 'import lldb.formatters, lldb.formatters.cpp, pydoc')", 566061da546Spatrick m_dictionary_name.c_str()); 567061da546Spatrick PyRun_SimpleString(run_string.GetData()); 568061da546Spatrick run_string.Clear(); 569061da546Spatrick 570061da546Spatrick run_string.Printf("run_one_line (%s, 'import lldb.embedded_interpreter; from " 571061da546Spatrick "lldb.embedded_interpreter import run_python_interpreter; " 572061da546Spatrick "from lldb.embedded_interpreter import run_one_line')", 573061da546Spatrick m_dictionary_name.c_str()); 574061da546Spatrick PyRun_SimpleString(run_string.GetData()); 575061da546Spatrick run_string.Clear(); 576061da546Spatrick 577061da546Spatrick run_string.Printf("run_one_line (%s, 'lldb.debugger_unique_id = %" PRIu64 578061da546Spatrick "; pydoc.pager = pydoc.plainpager')", 579061da546Spatrick m_dictionary_name.c_str(), m_debugger.GetID()); 580061da546Spatrick PyRun_SimpleString(run_string.GetData()); 581061da546Spatrick } 582061da546Spatrick 583061da546Spatrick ScriptInterpreterPythonImpl::~ScriptInterpreterPythonImpl() { 584061da546Spatrick // the session dictionary may hold objects with complex state which means 585061da546Spatrick // that they may need to be torn down with some level of smarts and that, in 586061da546Spatrick // turn, requires a valid thread state force Python to procure itself such a 587061da546Spatrick // thread state, nuke the session dictionary and then release it for others 588061da546Spatrick // to use and proceed with the rest of the shutdown 589061da546Spatrick auto gil_state = PyGILState_Ensure(); 590061da546Spatrick m_session_dict.Reset(); 591061da546Spatrick PyGILState_Release(gil_state); 592061da546Spatrick } 593061da546Spatrick 594061da546Spatrick lldb_private::ConstString ScriptInterpreterPythonImpl::GetPluginName() { 595061da546Spatrick return GetPluginNameStatic(); 596061da546Spatrick } 597061da546Spatrick 598061da546Spatrick uint32_t ScriptInterpreterPythonImpl::GetPluginVersion() { return 1; } 599061da546Spatrick 600061da546Spatrick void ScriptInterpreterPythonImpl::IOHandlerActivated(IOHandler &io_handler, 601061da546Spatrick bool interactive) { 602061da546Spatrick const char *instructions = nullptr; 603061da546Spatrick 604061da546Spatrick switch (m_active_io_handler) { 605061da546Spatrick case eIOHandlerNone: 606061da546Spatrick break; 607061da546Spatrick case eIOHandlerBreakpoint: 608061da546Spatrick instructions = R"(Enter your Python command(s). Type 'DONE' to end. 609061da546Spatrick def function (frame, bp_loc, internal_dict): 610061da546Spatrick """frame: the lldb.SBFrame for the location at which you stopped 611061da546Spatrick bp_loc: an lldb.SBBreakpointLocation for the breakpoint location information 612061da546Spatrick internal_dict: an LLDB support object not to be used""" 613061da546Spatrick )"; 614061da546Spatrick break; 615061da546Spatrick case eIOHandlerWatchpoint: 616061da546Spatrick instructions = "Enter your Python command(s). Type 'DONE' to end.\n"; 617061da546Spatrick break; 618061da546Spatrick } 619061da546Spatrick 620061da546Spatrick if (instructions) { 621061da546Spatrick StreamFileSP output_sp(io_handler.GetOutputStreamFileSP()); 622061da546Spatrick if (output_sp && interactive) { 623061da546Spatrick output_sp->PutCString(instructions); 624061da546Spatrick output_sp->Flush(); 625061da546Spatrick } 626061da546Spatrick } 627061da546Spatrick } 628061da546Spatrick 629061da546Spatrick void ScriptInterpreterPythonImpl::IOHandlerInputComplete(IOHandler &io_handler, 630061da546Spatrick std::string &data) { 631061da546Spatrick io_handler.SetIsDone(true); 632061da546Spatrick bool batch_mode = m_debugger.GetCommandInterpreter().GetBatchCommandMode(); 633061da546Spatrick 634061da546Spatrick switch (m_active_io_handler) { 635061da546Spatrick case eIOHandlerNone: 636061da546Spatrick break; 637061da546Spatrick case eIOHandlerBreakpoint: { 638*be691f3bSpatrick std::vector<std::reference_wrapper<BreakpointOptions>> *bp_options_vec = 639*be691f3bSpatrick (std::vector<std::reference_wrapper<BreakpointOptions>> *) 640*be691f3bSpatrick io_handler.GetUserData(); 641*be691f3bSpatrick for (BreakpointOptions &bp_options : *bp_options_vec) { 642061da546Spatrick 643061da546Spatrick auto data_up = std::make_unique<CommandDataPython>(); 644061da546Spatrick if (!data_up) 645061da546Spatrick break; 646061da546Spatrick data_up->user_source.SplitIntoLines(data); 647061da546Spatrick 648061da546Spatrick StructuredData::ObjectSP empty_args_sp; 649061da546Spatrick if (GenerateBreakpointCommandCallbackData(data_up->user_source, 650061da546Spatrick data_up->script_source, 651061da546Spatrick false) 652061da546Spatrick .Success()) { 653061da546Spatrick auto baton_sp = std::make_shared<BreakpointOptions::CommandBaton>( 654061da546Spatrick std::move(data_up)); 655*be691f3bSpatrick bp_options.SetCallback( 656061da546Spatrick ScriptInterpreterPythonImpl::BreakpointCallbackFunction, baton_sp); 657061da546Spatrick } else if (!batch_mode) { 658061da546Spatrick StreamFileSP error_sp = io_handler.GetErrorStreamFileSP(); 659061da546Spatrick if (error_sp) { 660061da546Spatrick error_sp->Printf("Warning: No command attached to breakpoint.\n"); 661061da546Spatrick error_sp->Flush(); 662061da546Spatrick } 663061da546Spatrick } 664061da546Spatrick } 665061da546Spatrick m_active_io_handler = eIOHandlerNone; 666061da546Spatrick } break; 667061da546Spatrick case eIOHandlerWatchpoint: { 668061da546Spatrick WatchpointOptions *wp_options = 669061da546Spatrick (WatchpointOptions *)io_handler.GetUserData(); 670061da546Spatrick auto data_up = std::make_unique<WatchpointOptions::CommandData>(); 671061da546Spatrick data_up->user_source.SplitIntoLines(data); 672061da546Spatrick 673061da546Spatrick if (GenerateWatchpointCommandCallbackData(data_up->user_source, 674061da546Spatrick data_up->script_source)) { 675061da546Spatrick auto baton_sp = 676061da546Spatrick std::make_shared<WatchpointOptions::CommandBaton>(std::move(data_up)); 677061da546Spatrick wp_options->SetCallback( 678061da546Spatrick ScriptInterpreterPythonImpl::WatchpointCallbackFunction, baton_sp); 679061da546Spatrick } else if (!batch_mode) { 680061da546Spatrick StreamFileSP error_sp = io_handler.GetErrorStreamFileSP(); 681061da546Spatrick if (error_sp) { 682061da546Spatrick error_sp->Printf("Warning: No command attached to breakpoint.\n"); 683061da546Spatrick error_sp->Flush(); 684061da546Spatrick } 685061da546Spatrick } 686061da546Spatrick m_active_io_handler = eIOHandlerNone; 687061da546Spatrick } break; 688061da546Spatrick } 689061da546Spatrick } 690061da546Spatrick 691061da546Spatrick lldb::ScriptInterpreterSP 692061da546Spatrick ScriptInterpreterPythonImpl::CreateInstance(Debugger &debugger) { 693061da546Spatrick return std::make_shared<ScriptInterpreterPythonImpl>(debugger); 694061da546Spatrick } 695061da546Spatrick 696061da546Spatrick void ScriptInterpreterPythonImpl::LeaveSession() { 697061da546Spatrick Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SCRIPT)); 698061da546Spatrick if (log) 699061da546Spatrick log->PutCString("ScriptInterpreterPythonImpl::LeaveSession()"); 700061da546Spatrick 701061da546Spatrick // Unset the LLDB global variables. 702061da546Spatrick PyRun_SimpleString("lldb.debugger = None; lldb.target = None; lldb.process " 703061da546Spatrick "= None; lldb.thread = None; lldb.frame = None"); 704061da546Spatrick 705061da546Spatrick // checking that we have a valid thread state - since we use our own 706061da546Spatrick // threading and locking in some (rare) cases during cleanup Python may end 707061da546Spatrick // up believing we have no thread state and PyImport_AddModule will crash if 708061da546Spatrick // that is the case - since that seems to only happen when destroying the 709061da546Spatrick // SBDebugger, we can make do without clearing up stdout and stderr 710061da546Spatrick 711061da546Spatrick // rdar://problem/11292882 712061da546Spatrick // When the current thread state is NULL, PyThreadState_Get() issues a fatal 713061da546Spatrick // error. 714061da546Spatrick if (PyThreadState_GetDict()) { 715061da546Spatrick PythonDictionary &sys_module_dict = GetSysModuleDictionary(); 716061da546Spatrick if (sys_module_dict.IsValid()) { 717061da546Spatrick if (m_saved_stdin.IsValid()) { 718061da546Spatrick sys_module_dict.SetItemForKey(PythonString("stdin"), m_saved_stdin); 719061da546Spatrick m_saved_stdin.Reset(); 720061da546Spatrick } 721061da546Spatrick if (m_saved_stdout.IsValid()) { 722061da546Spatrick sys_module_dict.SetItemForKey(PythonString("stdout"), m_saved_stdout); 723061da546Spatrick m_saved_stdout.Reset(); 724061da546Spatrick } 725061da546Spatrick if (m_saved_stderr.IsValid()) { 726061da546Spatrick sys_module_dict.SetItemForKey(PythonString("stderr"), m_saved_stderr); 727061da546Spatrick m_saved_stderr.Reset(); 728061da546Spatrick } 729061da546Spatrick } 730061da546Spatrick } 731061da546Spatrick 732061da546Spatrick m_session_is_active = false; 733061da546Spatrick } 734061da546Spatrick 735061da546Spatrick bool ScriptInterpreterPythonImpl::SetStdHandle(FileSP file_sp, 736061da546Spatrick const char *py_name, 737061da546Spatrick PythonObject &save_file, 738061da546Spatrick const char *mode) { 739061da546Spatrick if (!file_sp || !*file_sp) { 740061da546Spatrick save_file.Reset(); 741061da546Spatrick return false; 742061da546Spatrick } 743061da546Spatrick File &file = *file_sp; 744061da546Spatrick 745061da546Spatrick // Flush the file before giving it to python to avoid interleaved output. 746061da546Spatrick file.Flush(); 747061da546Spatrick 748061da546Spatrick PythonDictionary &sys_module_dict = GetSysModuleDictionary(); 749061da546Spatrick 750061da546Spatrick auto new_file = PythonFile::FromFile(file, mode); 751061da546Spatrick if (!new_file) { 752061da546Spatrick llvm::consumeError(new_file.takeError()); 753061da546Spatrick return false; 754061da546Spatrick } 755061da546Spatrick 756061da546Spatrick save_file = sys_module_dict.GetItemForKey(PythonString(py_name)); 757061da546Spatrick 758061da546Spatrick sys_module_dict.SetItemForKey(PythonString(py_name), new_file.get()); 759061da546Spatrick return true; 760061da546Spatrick } 761061da546Spatrick 762061da546Spatrick bool ScriptInterpreterPythonImpl::EnterSession(uint16_t on_entry_flags, 763061da546Spatrick FileSP in_sp, FileSP out_sp, 764061da546Spatrick FileSP err_sp) { 765061da546Spatrick // If we have already entered the session, without having officially 'left' 766061da546Spatrick // it, then there is no need to 'enter' it again. 767061da546Spatrick Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SCRIPT)); 768061da546Spatrick if (m_session_is_active) { 769061da546Spatrick LLDB_LOGF( 770061da546Spatrick log, 771061da546Spatrick "ScriptInterpreterPythonImpl::EnterSession(on_entry_flags=0x%" PRIx16 772061da546Spatrick ") session is already active, returning without doing anything", 773061da546Spatrick on_entry_flags); 774061da546Spatrick return false; 775061da546Spatrick } 776061da546Spatrick 777061da546Spatrick LLDB_LOGF( 778061da546Spatrick log, 779061da546Spatrick "ScriptInterpreterPythonImpl::EnterSession(on_entry_flags=0x%" PRIx16 ")", 780061da546Spatrick on_entry_flags); 781061da546Spatrick 782061da546Spatrick m_session_is_active = true; 783061da546Spatrick 784061da546Spatrick StreamString run_string; 785061da546Spatrick 786061da546Spatrick if (on_entry_flags & Locker::InitGlobals) { 787061da546Spatrick run_string.Printf("run_one_line (%s, 'lldb.debugger_unique_id = %" PRIu64, 788061da546Spatrick m_dictionary_name.c_str(), m_debugger.GetID()); 789061da546Spatrick run_string.Printf( 790061da546Spatrick "; lldb.debugger = lldb.SBDebugger.FindDebuggerWithID (%" PRIu64 ")", 791061da546Spatrick m_debugger.GetID()); 792061da546Spatrick run_string.PutCString("; lldb.target = lldb.debugger.GetSelectedTarget()"); 793061da546Spatrick run_string.PutCString("; lldb.process = lldb.target.GetProcess()"); 794061da546Spatrick run_string.PutCString("; lldb.thread = lldb.process.GetSelectedThread ()"); 795061da546Spatrick run_string.PutCString("; lldb.frame = lldb.thread.GetSelectedFrame ()"); 796061da546Spatrick run_string.PutCString("')"); 797061da546Spatrick } else { 798061da546Spatrick // If we aren't initing the globals, we should still always set the 799061da546Spatrick // debugger (since that is always unique.) 800061da546Spatrick run_string.Printf("run_one_line (%s, 'lldb.debugger_unique_id = %" PRIu64, 801061da546Spatrick m_dictionary_name.c_str(), m_debugger.GetID()); 802061da546Spatrick run_string.Printf( 803061da546Spatrick "; lldb.debugger = lldb.SBDebugger.FindDebuggerWithID (%" PRIu64 ")", 804061da546Spatrick m_debugger.GetID()); 805061da546Spatrick run_string.PutCString("')"); 806061da546Spatrick } 807061da546Spatrick 808061da546Spatrick PyRun_SimpleString(run_string.GetData()); 809061da546Spatrick run_string.Clear(); 810061da546Spatrick 811061da546Spatrick PythonDictionary &sys_module_dict = GetSysModuleDictionary(); 812061da546Spatrick if (sys_module_dict.IsValid()) { 813061da546Spatrick lldb::FileSP top_in_sp; 814061da546Spatrick lldb::StreamFileSP top_out_sp, top_err_sp; 815061da546Spatrick if (!in_sp || !out_sp || !err_sp || !*in_sp || !*out_sp || !*err_sp) 816061da546Spatrick m_debugger.AdoptTopIOHandlerFilesIfInvalid(top_in_sp, top_out_sp, 817061da546Spatrick top_err_sp); 818061da546Spatrick 819061da546Spatrick if (on_entry_flags & Locker::NoSTDIN) { 820061da546Spatrick m_saved_stdin.Reset(); 821061da546Spatrick } else { 822061da546Spatrick if (!SetStdHandle(in_sp, "stdin", m_saved_stdin, "r")) { 823061da546Spatrick if (top_in_sp) 824061da546Spatrick SetStdHandle(top_in_sp, "stdin", m_saved_stdin, "r"); 825061da546Spatrick } 826061da546Spatrick } 827061da546Spatrick 828061da546Spatrick if (!SetStdHandle(out_sp, "stdout", m_saved_stdout, "w")) { 829061da546Spatrick if (top_out_sp) 830061da546Spatrick SetStdHandle(top_out_sp->GetFileSP(), "stdout", m_saved_stdout, "w"); 831061da546Spatrick } 832061da546Spatrick 833061da546Spatrick if (!SetStdHandle(err_sp, "stderr", m_saved_stderr, "w")) { 834061da546Spatrick if (top_err_sp) 835061da546Spatrick SetStdHandle(top_err_sp->GetFileSP(), "stderr", m_saved_stderr, "w"); 836061da546Spatrick } 837061da546Spatrick } 838061da546Spatrick 839061da546Spatrick if (PyErr_Occurred()) 840061da546Spatrick PyErr_Clear(); 841061da546Spatrick 842061da546Spatrick return true; 843061da546Spatrick } 844061da546Spatrick 845061da546Spatrick PythonModule &ScriptInterpreterPythonImpl::GetMainModule() { 846061da546Spatrick if (!m_main_module.IsValid()) 847061da546Spatrick m_main_module = unwrapIgnoringErrors(PythonModule::Import("__main__")); 848061da546Spatrick return m_main_module; 849061da546Spatrick } 850061da546Spatrick 851061da546Spatrick PythonDictionary &ScriptInterpreterPythonImpl::GetSessionDictionary() { 852061da546Spatrick if (m_session_dict.IsValid()) 853061da546Spatrick return m_session_dict; 854061da546Spatrick 855061da546Spatrick PythonObject &main_module = GetMainModule(); 856061da546Spatrick if (!main_module.IsValid()) 857061da546Spatrick return m_session_dict; 858061da546Spatrick 859061da546Spatrick PythonDictionary main_dict(PyRefType::Borrowed, 860061da546Spatrick PyModule_GetDict(main_module.get())); 861061da546Spatrick if (!main_dict.IsValid()) 862061da546Spatrick return m_session_dict; 863061da546Spatrick 864061da546Spatrick m_session_dict = unwrapIgnoringErrors( 865061da546Spatrick As<PythonDictionary>(main_dict.GetItem(m_dictionary_name))); 866061da546Spatrick return m_session_dict; 867061da546Spatrick } 868061da546Spatrick 869061da546Spatrick PythonDictionary &ScriptInterpreterPythonImpl::GetSysModuleDictionary() { 870061da546Spatrick if (m_sys_module_dict.IsValid()) 871061da546Spatrick return m_sys_module_dict; 872061da546Spatrick PythonModule sys_module = unwrapIgnoringErrors(PythonModule::Import("sys")); 873061da546Spatrick m_sys_module_dict = sys_module.GetDictionary(); 874061da546Spatrick return m_sys_module_dict; 875061da546Spatrick } 876061da546Spatrick 877061da546Spatrick llvm::Expected<unsigned> 878061da546Spatrick ScriptInterpreterPythonImpl::GetMaxPositionalArgumentsForCallable( 879061da546Spatrick const llvm::StringRef &callable_name) { 880061da546Spatrick if (callable_name.empty()) { 881061da546Spatrick return llvm::createStringError( 882061da546Spatrick llvm::inconvertibleErrorCode(), 883061da546Spatrick "called with empty callable name."); 884061da546Spatrick } 885061da546Spatrick Locker py_lock(this, Locker::AcquireLock | 886061da546Spatrick Locker::InitSession | 887061da546Spatrick Locker::NoSTDIN); 888061da546Spatrick auto dict = PythonModule::MainModule() 889061da546Spatrick .ResolveName<PythonDictionary>(m_dictionary_name); 890061da546Spatrick auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>( 891061da546Spatrick callable_name, dict); 892061da546Spatrick if (!pfunc.IsAllocated()) { 893061da546Spatrick return llvm::createStringError( 894061da546Spatrick llvm::inconvertibleErrorCode(), 895061da546Spatrick "can't find callable: %s", callable_name.str().c_str()); 896061da546Spatrick } 897061da546Spatrick llvm::Expected<PythonCallable::ArgInfo> arg_info = pfunc.GetArgInfo(); 898061da546Spatrick if (!arg_info) 899061da546Spatrick return arg_info.takeError(); 900061da546Spatrick return arg_info.get().max_positional_args; 901061da546Spatrick } 902061da546Spatrick 903061da546Spatrick static std::string GenerateUniqueName(const char *base_name_wanted, 904061da546Spatrick uint32_t &functions_counter, 905061da546Spatrick const void *name_token = nullptr) { 906061da546Spatrick StreamString sstr; 907061da546Spatrick 908061da546Spatrick if (!base_name_wanted) 909061da546Spatrick return std::string(); 910061da546Spatrick 911061da546Spatrick if (!name_token) 912061da546Spatrick sstr.Printf("%s_%d", base_name_wanted, functions_counter++); 913061da546Spatrick else 914061da546Spatrick sstr.Printf("%s_%p", base_name_wanted, name_token); 915061da546Spatrick 916dda28197Spatrick return std::string(sstr.GetString()); 917061da546Spatrick } 918061da546Spatrick 919061da546Spatrick bool ScriptInterpreterPythonImpl::GetEmbeddedInterpreterModuleObjects() { 920061da546Spatrick if (m_run_one_line_function.IsValid()) 921061da546Spatrick return true; 922061da546Spatrick 923061da546Spatrick PythonObject module(PyRefType::Borrowed, 924061da546Spatrick PyImport_AddModule("lldb.embedded_interpreter")); 925061da546Spatrick if (!module.IsValid()) 926061da546Spatrick return false; 927061da546Spatrick 928061da546Spatrick PythonDictionary module_dict(PyRefType::Borrowed, 929061da546Spatrick PyModule_GetDict(module.get())); 930061da546Spatrick if (!module_dict.IsValid()) 931061da546Spatrick return false; 932061da546Spatrick 933061da546Spatrick m_run_one_line_function = 934061da546Spatrick module_dict.GetItemForKey(PythonString("run_one_line")); 935061da546Spatrick m_run_one_line_str_global = 936061da546Spatrick module_dict.GetItemForKey(PythonString("g_run_one_line_str")); 937061da546Spatrick return m_run_one_line_function.IsValid(); 938061da546Spatrick } 939061da546Spatrick 940061da546Spatrick bool ScriptInterpreterPythonImpl::ExecuteOneLine( 941061da546Spatrick llvm::StringRef command, CommandReturnObject *result, 942061da546Spatrick const ExecuteScriptOptions &options) { 943061da546Spatrick std::string command_str = command.str(); 944061da546Spatrick 945061da546Spatrick if (!m_valid_session) 946061da546Spatrick return false; 947061da546Spatrick 948061da546Spatrick if (!command.empty()) { 949061da546Spatrick // We want to call run_one_line, passing in the dictionary and the command 950061da546Spatrick // string. We cannot do this through PyRun_SimpleString here because the 951061da546Spatrick // command string may contain escaped characters, and putting it inside 952061da546Spatrick // another string to pass to PyRun_SimpleString messes up the escaping. So 953061da546Spatrick // we use the following more complicated method to pass the command string 954061da546Spatrick // directly down to Python. 955dda28197Spatrick llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>> 956dda28197Spatrick io_redirect_or_error = ScriptInterpreterIORedirect::Create( 957dda28197Spatrick options.GetEnableIO(), m_debugger, result); 958dda28197Spatrick if (!io_redirect_or_error) { 959dda28197Spatrick if (result) 960dda28197Spatrick result->AppendErrorWithFormatv( 961dda28197Spatrick "failed to redirect I/O: {0}\n", 962dda28197Spatrick llvm::fmt_consume(io_redirect_or_error.takeError())); 963dda28197Spatrick else 964dda28197Spatrick llvm::consumeError(io_redirect_or_error.takeError()); 965061da546Spatrick return false; 966061da546Spatrick } 967dda28197Spatrick 968dda28197Spatrick ScriptInterpreterIORedirect &io_redirect = **io_redirect_or_error; 969061da546Spatrick 970061da546Spatrick bool success = false; 971061da546Spatrick { 972061da546Spatrick // WARNING! It's imperative that this RAII scope be as tight as 973061da546Spatrick // possible. In particular, the scope must end *before* we try to join 974061da546Spatrick // the read thread. The reason for this is that a pre-requisite for 975061da546Spatrick // joining the read thread is that we close the write handle (to break 976061da546Spatrick // the pipe and cause it to wake up and exit). But acquiring the GIL as 977061da546Spatrick // below will redirect Python's stdio to use this same handle. If we 978061da546Spatrick // close the handle while Python is still using it, bad things will 979061da546Spatrick // happen. 980061da546Spatrick Locker locker( 981061da546Spatrick this, 982061da546Spatrick Locker::AcquireLock | Locker::InitSession | 983061da546Spatrick (options.GetSetLLDBGlobals() ? Locker::InitGlobals : 0) | 984061da546Spatrick ((result && result->GetInteractive()) ? 0 : Locker::NoSTDIN), 985dda28197Spatrick Locker::FreeAcquiredLock | Locker::TearDownSession, 986dda28197Spatrick io_redirect.GetInputFile(), io_redirect.GetOutputFile(), 987dda28197Spatrick io_redirect.GetErrorFile()); 988061da546Spatrick 989061da546Spatrick // Find the correct script interpreter dictionary in the main module. 990061da546Spatrick PythonDictionary &session_dict = GetSessionDictionary(); 991061da546Spatrick if (session_dict.IsValid()) { 992061da546Spatrick if (GetEmbeddedInterpreterModuleObjects()) { 993061da546Spatrick if (PyCallable_Check(m_run_one_line_function.get())) { 994061da546Spatrick PythonObject pargs( 995061da546Spatrick PyRefType::Owned, 996061da546Spatrick Py_BuildValue("(Os)", session_dict.get(), command_str.c_str())); 997061da546Spatrick if (pargs.IsValid()) { 998061da546Spatrick PythonObject return_value( 999061da546Spatrick PyRefType::Owned, 1000061da546Spatrick PyObject_CallObject(m_run_one_line_function.get(), 1001061da546Spatrick pargs.get())); 1002061da546Spatrick if (return_value.IsValid()) 1003061da546Spatrick success = true; 1004061da546Spatrick else if (options.GetMaskoutErrors() && PyErr_Occurred()) { 1005061da546Spatrick PyErr_Print(); 1006061da546Spatrick PyErr_Clear(); 1007061da546Spatrick } 1008061da546Spatrick } 1009061da546Spatrick } 1010061da546Spatrick } 1011061da546Spatrick } 1012061da546Spatrick 1013dda28197Spatrick io_redirect.Flush(); 1014061da546Spatrick } 1015061da546Spatrick 1016061da546Spatrick if (success) 1017061da546Spatrick return true; 1018061da546Spatrick 1019061da546Spatrick // The one-liner failed. Append the error message. 1020061da546Spatrick if (result) { 1021061da546Spatrick result->AppendErrorWithFormat( 1022061da546Spatrick "python failed attempting to evaluate '%s'\n", command_str.c_str()); 1023061da546Spatrick } 1024061da546Spatrick return false; 1025061da546Spatrick } 1026061da546Spatrick 1027061da546Spatrick if (result) 1028061da546Spatrick result->AppendError("empty command passed to python\n"); 1029061da546Spatrick return false; 1030061da546Spatrick } 1031061da546Spatrick 1032061da546Spatrick void ScriptInterpreterPythonImpl::ExecuteInterpreterLoop() { 1033*be691f3bSpatrick LLDB_SCOPED_TIMER(); 1034061da546Spatrick 1035061da546Spatrick Debugger &debugger = m_debugger; 1036061da546Spatrick 1037061da546Spatrick // At the moment, the only time the debugger does not have an input file 1038061da546Spatrick // handle is when this is called directly from Python, in which case it is 1039061da546Spatrick // both dangerous and unnecessary (not to mention confusing) to try to embed 1040061da546Spatrick // a running interpreter loop inside the already running Python interpreter 1041061da546Spatrick // loop, so we won't do it. 1042061da546Spatrick 1043061da546Spatrick if (!debugger.GetInputFile().IsValid()) 1044061da546Spatrick return; 1045061da546Spatrick 1046061da546Spatrick IOHandlerSP io_handler_sp(new IOHandlerPythonInterpreter(debugger, this)); 1047061da546Spatrick if (io_handler_sp) { 1048dda28197Spatrick debugger.RunIOHandlerAsync(io_handler_sp); 1049061da546Spatrick } 1050061da546Spatrick } 1051061da546Spatrick 1052061da546Spatrick bool ScriptInterpreterPythonImpl::Interrupt() { 1053061da546Spatrick Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SCRIPT)); 1054061da546Spatrick 1055061da546Spatrick if (IsExecutingPython()) { 1056061da546Spatrick PyThreadState *state = PyThreadState_GET(); 1057061da546Spatrick if (!state) 1058061da546Spatrick state = GetThreadState(); 1059061da546Spatrick if (state) { 1060061da546Spatrick long tid = state->thread_id; 1061061da546Spatrick PyThreadState_Swap(state); 1062061da546Spatrick int num_threads = PyThreadState_SetAsyncExc(tid, PyExc_KeyboardInterrupt); 1063061da546Spatrick LLDB_LOGF(log, 1064061da546Spatrick "ScriptInterpreterPythonImpl::Interrupt() sending " 1065061da546Spatrick "PyExc_KeyboardInterrupt (tid = %li, num_threads = %i)...", 1066061da546Spatrick tid, num_threads); 1067061da546Spatrick return true; 1068061da546Spatrick } 1069061da546Spatrick } 1070061da546Spatrick LLDB_LOGF(log, 1071061da546Spatrick "ScriptInterpreterPythonImpl::Interrupt() python code not running, " 1072061da546Spatrick "can't interrupt"); 1073061da546Spatrick return false; 1074061da546Spatrick } 1075061da546Spatrick 1076061da546Spatrick bool ScriptInterpreterPythonImpl::ExecuteOneLineWithReturn( 1077061da546Spatrick llvm::StringRef in_string, ScriptInterpreter::ScriptReturnType return_type, 1078061da546Spatrick void *ret_value, const ExecuteScriptOptions &options) { 1079061da546Spatrick 1080*be691f3bSpatrick llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>> 1081*be691f3bSpatrick io_redirect_or_error = ScriptInterpreterIORedirect::Create( 1082*be691f3bSpatrick options.GetEnableIO(), m_debugger, /*result=*/nullptr); 1083*be691f3bSpatrick 1084*be691f3bSpatrick if (!io_redirect_or_error) { 1085*be691f3bSpatrick llvm::consumeError(io_redirect_or_error.takeError()); 1086*be691f3bSpatrick return false; 1087*be691f3bSpatrick } 1088*be691f3bSpatrick 1089*be691f3bSpatrick ScriptInterpreterIORedirect &io_redirect = **io_redirect_or_error; 1090*be691f3bSpatrick 1091061da546Spatrick Locker locker(this, 1092061da546Spatrick Locker::AcquireLock | Locker::InitSession | 1093061da546Spatrick (options.GetSetLLDBGlobals() ? Locker::InitGlobals : 0) | 1094061da546Spatrick Locker::NoSTDIN, 1095*be691f3bSpatrick Locker::FreeAcquiredLock | Locker::TearDownSession, 1096*be691f3bSpatrick io_redirect.GetInputFile(), io_redirect.GetOutputFile(), 1097*be691f3bSpatrick io_redirect.GetErrorFile()); 1098061da546Spatrick 1099061da546Spatrick PythonModule &main_module = GetMainModule(); 1100061da546Spatrick PythonDictionary globals = main_module.GetDictionary(); 1101061da546Spatrick 1102061da546Spatrick PythonDictionary locals = GetSessionDictionary(); 1103061da546Spatrick if (!locals.IsValid()) 1104061da546Spatrick locals = unwrapIgnoringErrors( 1105061da546Spatrick As<PythonDictionary>(globals.GetAttribute(m_dictionary_name))); 1106061da546Spatrick if (!locals.IsValid()) 1107061da546Spatrick locals = globals; 1108061da546Spatrick 1109061da546Spatrick Expected<PythonObject> maybe_py_return = 1110061da546Spatrick runStringOneLine(in_string, globals, locals); 1111061da546Spatrick 1112061da546Spatrick if (!maybe_py_return) { 1113061da546Spatrick llvm::handleAllErrors( 1114061da546Spatrick maybe_py_return.takeError(), 1115061da546Spatrick [&](PythonException &E) { 1116061da546Spatrick E.Restore(); 1117061da546Spatrick if (options.GetMaskoutErrors()) { 1118061da546Spatrick if (E.Matches(PyExc_SyntaxError)) { 1119061da546Spatrick PyErr_Print(); 1120061da546Spatrick } 1121061da546Spatrick PyErr_Clear(); 1122061da546Spatrick } 1123061da546Spatrick }, 1124061da546Spatrick [](const llvm::ErrorInfoBase &E) {}); 1125061da546Spatrick return false; 1126061da546Spatrick } 1127061da546Spatrick 1128061da546Spatrick PythonObject py_return = std::move(maybe_py_return.get()); 1129061da546Spatrick assert(py_return.IsValid()); 1130061da546Spatrick 1131061da546Spatrick switch (return_type) { 1132061da546Spatrick case eScriptReturnTypeCharPtr: // "char *" 1133061da546Spatrick { 1134061da546Spatrick const char format[3] = "s#"; 1135061da546Spatrick return PyArg_Parse(py_return.get(), format, (char **)ret_value); 1136061da546Spatrick } 1137061da546Spatrick case eScriptReturnTypeCharStrOrNone: // char* or NULL if py_return == 1138061da546Spatrick // Py_None 1139061da546Spatrick { 1140061da546Spatrick const char format[3] = "z"; 1141061da546Spatrick return PyArg_Parse(py_return.get(), format, (char **)ret_value); 1142061da546Spatrick } 1143061da546Spatrick case eScriptReturnTypeBool: { 1144061da546Spatrick const char format[2] = "b"; 1145061da546Spatrick return PyArg_Parse(py_return.get(), format, (bool *)ret_value); 1146061da546Spatrick } 1147061da546Spatrick case eScriptReturnTypeShortInt: { 1148061da546Spatrick const char format[2] = "h"; 1149061da546Spatrick return PyArg_Parse(py_return.get(), format, (short *)ret_value); 1150061da546Spatrick } 1151061da546Spatrick case eScriptReturnTypeShortIntUnsigned: { 1152061da546Spatrick const char format[2] = "H"; 1153061da546Spatrick return PyArg_Parse(py_return.get(), format, (unsigned short *)ret_value); 1154061da546Spatrick } 1155061da546Spatrick case eScriptReturnTypeInt: { 1156061da546Spatrick const char format[2] = "i"; 1157061da546Spatrick return PyArg_Parse(py_return.get(), format, (int *)ret_value); 1158061da546Spatrick } 1159061da546Spatrick case eScriptReturnTypeIntUnsigned: { 1160061da546Spatrick const char format[2] = "I"; 1161061da546Spatrick return PyArg_Parse(py_return.get(), format, (unsigned int *)ret_value); 1162061da546Spatrick } 1163061da546Spatrick case eScriptReturnTypeLongInt: { 1164061da546Spatrick const char format[2] = "l"; 1165061da546Spatrick return PyArg_Parse(py_return.get(), format, (long *)ret_value); 1166061da546Spatrick } 1167061da546Spatrick case eScriptReturnTypeLongIntUnsigned: { 1168061da546Spatrick const char format[2] = "k"; 1169061da546Spatrick return PyArg_Parse(py_return.get(), format, (unsigned long *)ret_value); 1170061da546Spatrick } 1171061da546Spatrick case eScriptReturnTypeLongLong: { 1172061da546Spatrick const char format[2] = "L"; 1173061da546Spatrick return PyArg_Parse(py_return.get(), format, (long long *)ret_value); 1174061da546Spatrick } 1175061da546Spatrick case eScriptReturnTypeLongLongUnsigned: { 1176061da546Spatrick const char format[2] = "K"; 1177061da546Spatrick return PyArg_Parse(py_return.get(), format, 1178061da546Spatrick (unsigned long long *)ret_value); 1179061da546Spatrick } 1180061da546Spatrick case eScriptReturnTypeFloat: { 1181061da546Spatrick const char format[2] = "f"; 1182061da546Spatrick return PyArg_Parse(py_return.get(), format, (float *)ret_value); 1183061da546Spatrick } 1184061da546Spatrick case eScriptReturnTypeDouble: { 1185061da546Spatrick const char format[2] = "d"; 1186061da546Spatrick return PyArg_Parse(py_return.get(), format, (double *)ret_value); 1187061da546Spatrick } 1188061da546Spatrick case eScriptReturnTypeChar: { 1189061da546Spatrick const char format[2] = "c"; 1190061da546Spatrick return PyArg_Parse(py_return.get(), format, (char *)ret_value); 1191061da546Spatrick } 1192061da546Spatrick case eScriptReturnTypeOpaqueObject: { 1193061da546Spatrick *((PyObject **)ret_value) = py_return.release(); 1194061da546Spatrick return true; 1195061da546Spatrick } 1196061da546Spatrick } 1197061da546Spatrick llvm_unreachable("Fully covered switch!"); 1198061da546Spatrick } 1199061da546Spatrick 1200061da546Spatrick Status ScriptInterpreterPythonImpl::ExecuteMultipleLines( 1201061da546Spatrick const char *in_string, const ExecuteScriptOptions &options) { 1202061da546Spatrick 1203061da546Spatrick if (in_string == nullptr) 1204061da546Spatrick return Status(); 1205061da546Spatrick 1206*be691f3bSpatrick llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>> 1207*be691f3bSpatrick io_redirect_or_error = ScriptInterpreterIORedirect::Create( 1208*be691f3bSpatrick options.GetEnableIO(), m_debugger, /*result=*/nullptr); 1209*be691f3bSpatrick 1210*be691f3bSpatrick if (!io_redirect_or_error) 1211*be691f3bSpatrick return Status(io_redirect_or_error.takeError()); 1212*be691f3bSpatrick 1213*be691f3bSpatrick ScriptInterpreterIORedirect &io_redirect = **io_redirect_or_error; 1214*be691f3bSpatrick 1215061da546Spatrick Locker locker(this, 1216061da546Spatrick Locker::AcquireLock | Locker::InitSession | 1217061da546Spatrick (options.GetSetLLDBGlobals() ? Locker::InitGlobals : 0) | 1218061da546Spatrick Locker::NoSTDIN, 1219*be691f3bSpatrick Locker::FreeAcquiredLock | Locker::TearDownSession, 1220*be691f3bSpatrick io_redirect.GetInputFile(), io_redirect.GetOutputFile(), 1221*be691f3bSpatrick io_redirect.GetErrorFile()); 1222061da546Spatrick 1223061da546Spatrick PythonModule &main_module = GetMainModule(); 1224061da546Spatrick PythonDictionary globals = main_module.GetDictionary(); 1225061da546Spatrick 1226061da546Spatrick PythonDictionary locals = GetSessionDictionary(); 1227061da546Spatrick if (!locals.IsValid()) 1228061da546Spatrick locals = unwrapIgnoringErrors( 1229061da546Spatrick As<PythonDictionary>(globals.GetAttribute(m_dictionary_name))); 1230061da546Spatrick if (!locals.IsValid()) 1231061da546Spatrick locals = globals; 1232061da546Spatrick 1233061da546Spatrick Expected<PythonObject> return_value = 1234061da546Spatrick runStringMultiLine(in_string, globals, locals); 1235061da546Spatrick 1236061da546Spatrick if (!return_value) { 1237061da546Spatrick llvm::Error error = 1238061da546Spatrick llvm::handleErrors(return_value.takeError(), [&](PythonException &E) { 1239061da546Spatrick llvm::Error error = llvm::createStringError( 1240061da546Spatrick llvm::inconvertibleErrorCode(), E.ReadBacktrace()); 1241061da546Spatrick if (!options.GetMaskoutErrors()) 1242061da546Spatrick E.Restore(); 1243061da546Spatrick return error; 1244061da546Spatrick }); 1245061da546Spatrick return Status(std::move(error)); 1246061da546Spatrick } 1247061da546Spatrick 1248061da546Spatrick return Status(); 1249061da546Spatrick } 1250061da546Spatrick 1251061da546Spatrick void ScriptInterpreterPythonImpl::CollectDataForBreakpointCommandCallback( 1252*be691f3bSpatrick std::vector<std::reference_wrapper<BreakpointOptions>> &bp_options_vec, 1253061da546Spatrick CommandReturnObject &result) { 1254061da546Spatrick m_active_io_handler = eIOHandlerBreakpoint; 1255061da546Spatrick m_debugger.GetCommandInterpreter().GetPythonCommandsFromIOHandler( 1256061da546Spatrick " ", *this, &bp_options_vec); 1257061da546Spatrick } 1258061da546Spatrick 1259061da546Spatrick void ScriptInterpreterPythonImpl::CollectDataForWatchpointCommandCallback( 1260061da546Spatrick WatchpointOptions *wp_options, CommandReturnObject &result) { 1261061da546Spatrick m_active_io_handler = eIOHandlerWatchpoint; 1262061da546Spatrick m_debugger.GetCommandInterpreter().GetPythonCommandsFromIOHandler( 1263061da546Spatrick " ", *this, wp_options); 1264061da546Spatrick } 1265061da546Spatrick 1266061da546Spatrick Status ScriptInterpreterPythonImpl::SetBreakpointCommandCallbackFunction( 1267*be691f3bSpatrick BreakpointOptions &bp_options, const char *function_name, 1268061da546Spatrick StructuredData::ObjectSP extra_args_sp) { 1269061da546Spatrick Status error; 1270061da546Spatrick // For now just cons up a oneliner that calls the provided function. 1271061da546Spatrick std::string oneliner("return "); 1272061da546Spatrick oneliner += function_name; 1273061da546Spatrick 1274061da546Spatrick llvm::Expected<unsigned> maybe_args = 1275061da546Spatrick GetMaxPositionalArgumentsForCallable(function_name); 1276061da546Spatrick if (!maybe_args) { 1277061da546Spatrick error.SetErrorStringWithFormat( 1278061da546Spatrick "could not get num args: %s", 1279061da546Spatrick llvm::toString(maybe_args.takeError()).c_str()); 1280061da546Spatrick return error; 1281061da546Spatrick } 1282061da546Spatrick size_t max_args = *maybe_args; 1283061da546Spatrick 1284061da546Spatrick bool uses_extra_args = false; 1285061da546Spatrick if (max_args >= 4) { 1286061da546Spatrick uses_extra_args = true; 1287061da546Spatrick oneliner += "(frame, bp_loc, extra_args, internal_dict)"; 1288061da546Spatrick } else if (max_args >= 3) { 1289061da546Spatrick if (extra_args_sp) { 1290061da546Spatrick error.SetErrorString("cannot pass extra_args to a three argument callback" 1291061da546Spatrick ); 1292061da546Spatrick return error; 1293061da546Spatrick } 1294061da546Spatrick uses_extra_args = false; 1295061da546Spatrick oneliner += "(frame, bp_loc, internal_dict)"; 1296061da546Spatrick } else { 1297061da546Spatrick error.SetErrorStringWithFormat("expected 3 or 4 argument " 1298061da546Spatrick "function, %s can only take %zu", 1299061da546Spatrick function_name, max_args); 1300061da546Spatrick return error; 1301061da546Spatrick } 1302061da546Spatrick 1303061da546Spatrick SetBreakpointCommandCallback(bp_options, oneliner.c_str(), extra_args_sp, 1304061da546Spatrick uses_extra_args); 1305061da546Spatrick return error; 1306061da546Spatrick } 1307061da546Spatrick 1308061da546Spatrick Status ScriptInterpreterPythonImpl::SetBreakpointCommandCallback( 1309*be691f3bSpatrick BreakpointOptions &bp_options, 1310061da546Spatrick std::unique_ptr<BreakpointOptions::CommandData> &cmd_data_up) { 1311061da546Spatrick Status error; 1312061da546Spatrick error = GenerateBreakpointCommandCallbackData(cmd_data_up->user_source, 1313061da546Spatrick cmd_data_up->script_source, 1314061da546Spatrick false); 1315061da546Spatrick if (error.Fail()) { 1316061da546Spatrick return error; 1317061da546Spatrick } 1318061da546Spatrick auto baton_sp = 1319061da546Spatrick std::make_shared<BreakpointOptions::CommandBaton>(std::move(cmd_data_up)); 1320*be691f3bSpatrick bp_options.SetCallback( 1321061da546Spatrick ScriptInterpreterPythonImpl::BreakpointCallbackFunction, baton_sp); 1322061da546Spatrick return error; 1323061da546Spatrick } 1324061da546Spatrick 1325061da546Spatrick Status ScriptInterpreterPythonImpl::SetBreakpointCommandCallback( 1326*be691f3bSpatrick BreakpointOptions &bp_options, const char *command_body_text) { 1327061da546Spatrick return SetBreakpointCommandCallback(bp_options, command_body_text, {},false); 1328061da546Spatrick } 1329061da546Spatrick 1330061da546Spatrick // Set a Python one-liner as the callback for the breakpoint. 1331061da546Spatrick Status ScriptInterpreterPythonImpl::SetBreakpointCommandCallback( 1332*be691f3bSpatrick BreakpointOptions &bp_options, const char *command_body_text, 1333*be691f3bSpatrick StructuredData::ObjectSP extra_args_sp, bool uses_extra_args) { 1334061da546Spatrick auto data_up = std::make_unique<CommandDataPython>(extra_args_sp); 1335061da546Spatrick // Split the command_body_text into lines, and pass that to 1336061da546Spatrick // GenerateBreakpointCommandCallbackData. That will wrap the body in an 1337061da546Spatrick // auto-generated function, and return the function name in script_source. 1338061da546Spatrick // That is what the callback will actually invoke. 1339061da546Spatrick 1340061da546Spatrick data_up->user_source.SplitIntoLines(command_body_text); 1341061da546Spatrick Status error = GenerateBreakpointCommandCallbackData(data_up->user_source, 1342061da546Spatrick data_up->script_source, 1343061da546Spatrick uses_extra_args); 1344061da546Spatrick if (error.Success()) { 1345061da546Spatrick auto baton_sp = 1346061da546Spatrick std::make_shared<BreakpointOptions::CommandBaton>(std::move(data_up)); 1347*be691f3bSpatrick bp_options.SetCallback( 1348061da546Spatrick ScriptInterpreterPythonImpl::BreakpointCallbackFunction, baton_sp); 1349061da546Spatrick return error; 1350dda28197Spatrick } 1351061da546Spatrick return error; 1352061da546Spatrick } 1353061da546Spatrick 1354061da546Spatrick // Set a Python one-liner as the callback for the watchpoint. 1355061da546Spatrick void ScriptInterpreterPythonImpl::SetWatchpointCommandCallback( 1356061da546Spatrick WatchpointOptions *wp_options, const char *oneliner) { 1357061da546Spatrick auto data_up = std::make_unique<WatchpointOptions::CommandData>(); 1358061da546Spatrick 1359061da546Spatrick // It's necessary to set both user_source and script_source to the oneliner. 1360061da546Spatrick // The former is used to generate callback description (as in watchpoint 1361061da546Spatrick // command list) while the latter is used for Python to interpret during the 1362061da546Spatrick // actual callback. 1363061da546Spatrick 1364061da546Spatrick data_up->user_source.AppendString(oneliner); 1365061da546Spatrick data_up->script_source.assign(oneliner); 1366061da546Spatrick 1367061da546Spatrick if (GenerateWatchpointCommandCallbackData(data_up->user_source, 1368061da546Spatrick data_up->script_source)) { 1369061da546Spatrick auto baton_sp = 1370061da546Spatrick std::make_shared<WatchpointOptions::CommandBaton>(std::move(data_up)); 1371061da546Spatrick wp_options->SetCallback( 1372061da546Spatrick ScriptInterpreterPythonImpl::WatchpointCallbackFunction, baton_sp); 1373061da546Spatrick } 1374061da546Spatrick 1375061da546Spatrick return; 1376061da546Spatrick } 1377061da546Spatrick 1378061da546Spatrick Status ScriptInterpreterPythonImpl::ExportFunctionDefinitionToInterpreter( 1379061da546Spatrick StringList &function_def) { 1380061da546Spatrick // Convert StringList to one long, newline delimited, const char *. 1381061da546Spatrick std::string function_def_string(function_def.CopyList()); 1382061da546Spatrick 1383061da546Spatrick Status error = ExecuteMultipleLines( 1384061da546Spatrick function_def_string.c_str(), 1385*be691f3bSpatrick ExecuteScriptOptions().SetEnableIO(false)); 1386061da546Spatrick return error; 1387061da546Spatrick } 1388061da546Spatrick 1389061da546Spatrick Status ScriptInterpreterPythonImpl::GenerateFunction(const char *signature, 1390061da546Spatrick const StringList &input) { 1391061da546Spatrick Status error; 1392061da546Spatrick int num_lines = input.GetSize(); 1393061da546Spatrick if (num_lines == 0) { 1394061da546Spatrick error.SetErrorString("No input data."); 1395061da546Spatrick return error; 1396061da546Spatrick } 1397061da546Spatrick 1398061da546Spatrick if (!signature || *signature == 0) { 1399061da546Spatrick error.SetErrorString("No output function name."); 1400061da546Spatrick return error; 1401061da546Spatrick } 1402061da546Spatrick 1403061da546Spatrick StreamString sstr; 1404061da546Spatrick StringList auto_generated_function; 1405061da546Spatrick auto_generated_function.AppendString(signature); 1406061da546Spatrick auto_generated_function.AppendString( 1407061da546Spatrick " global_dict = globals()"); // Grab the global dictionary 1408061da546Spatrick auto_generated_function.AppendString( 1409061da546Spatrick " new_keys = internal_dict.keys()"); // Make a list of keys in the 1410061da546Spatrick // session dict 1411061da546Spatrick auto_generated_function.AppendString( 1412061da546Spatrick " old_keys = global_dict.keys()"); // Save list of keys in global dict 1413061da546Spatrick auto_generated_function.AppendString( 1414061da546Spatrick " global_dict.update (internal_dict)"); // Add the session dictionary 1415061da546Spatrick // to the 1416061da546Spatrick // global dictionary. 1417061da546Spatrick 1418061da546Spatrick // Wrap everything up inside the function, increasing the indentation. 1419061da546Spatrick 1420061da546Spatrick auto_generated_function.AppendString(" if True:"); 1421061da546Spatrick for (int i = 0; i < num_lines; ++i) { 1422061da546Spatrick sstr.Clear(); 1423061da546Spatrick sstr.Printf(" %s", input.GetStringAtIndex(i)); 1424061da546Spatrick auto_generated_function.AppendString(sstr.GetData()); 1425061da546Spatrick } 1426061da546Spatrick auto_generated_function.AppendString( 1427061da546Spatrick " for key in new_keys:"); // Iterate over all the keys from session 1428061da546Spatrick // dict 1429061da546Spatrick auto_generated_function.AppendString( 1430061da546Spatrick " internal_dict[key] = global_dict[key]"); // Update session dict 1431061da546Spatrick // values 1432061da546Spatrick auto_generated_function.AppendString( 1433061da546Spatrick " if key not in old_keys:"); // If key was not originally in 1434061da546Spatrick // global dict 1435061da546Spatrick auto_generated_function.AppendString( 1436061da546Spatrick " del global_dict[key]"); // ...then remove key/value from 1437061da546Spatrick // global dict 1438061da546Spatrick 1439061da546Spatrick // Verify that the results are valid Python. 1440061da546Spatrick 1441061da546Spatrick error = ExportFunctionDefinitionToInterpreter(auto_generated_function); 1442061da546Spatrick 1443061da546Spatrick return error; 1444061da546Spatrick } 1445061da546Spatrick 1446061da546Spatrick bool ScriptInterpreterPythonImpl::GenerateTypeScriptFunction( 1447061da546Spatrick StringList &user_input, std::string &output, const void *name_token) { 1448061da546Spatrick static uint32_t num_created_functions = 0; 1449061da546Spatrick user_input.RemoveBlankLines(); 1450061da546Spatrick StreamString sstr; 1451061da546Spatrick 1452061da546Spatrick // Check to see if we have any data; if not, just return. 1453061da546Spatrick if (user_input.GetSize() == 0) 1454061da546Spatrick return false; 1455061da546Spatrick 1456061da546Spatrick // Take what the user wrote, wrap it all up inside one big auto-generated 1457061da546Spatrick // Python function, passing in the ValueObject as parameter to the function. 1458061da546Spatrick 1459061da546Spatrick std::string auto_generated_function_name( 1460061da546Spatrick GenerateUniqueName("lldb_autogen_python_type_print_func", 1461061da546Spatrick num_created_functions, name_token)); 1462061da546Spatrick sstr.Printf("def %s (valobj, internal_dict):", 1463061da546Spatrick auto_generated_function_name.c_str()); 1464061da546Spatrick 1465061da546Spatrick if (!GenerateFunction(sstr.GetData(), user_input).Success()) 1466061da546Spatrick return false; 1467061da546Spatrick 1468061da546Spatrick // Store the name of the auto-generated function to be called. 1469061da546Spatrick output.assign(auto_generated_function_name); 1470061da546Spatrick return true; 1471061da546Spatrick } 1472061da546Spatrick 1473061da546Spatrick bool ScriptInterpreterPythonImpl::GenerateScriptAliasFunction( 1474061da546Spatrick StringList &user_input, std::string &output) { 1475061da546Spatrick static uint32_t num_created_functions = 0; 1476061da546Spatrick user_input.RemoveBlankLines(); 1477061da546Spatrick StreamString sstr; 1478061da546Spatrick 1479061da546Spatrick // Check to see if we have any data; if not, just return. 1480061da546Spatrick if (user_input.GetSize() == 0) 1481061da546Spatrick return false; 1482061da546Spatrick 1483061da546Spatrick std::string auto_generated_function_name(GenerateUniqueName( 1484061da546Spatrick "lldb_autogen_python_cmd_alias_func", num_created_functions)); 1485061da546Spatrick 1486061da546Spatrick sstr.Printf("def %s (debugger, args, result, internal_dict):", 1487061da546Spatrick auto_generated_function_name.c_str()); 1488061da546Spatrick 1489061da546Spatrick if (!GenerateFunction(sstr.GetData(), user_input).Success()) 1490061da546Spatrick return false; 1491061da546Spatrick 1492061da546Spatrick // Store the name of the auto-generated function to be called. 1493061da546Spatrick output.assign(auto_generated_function_name); 1494061da546Spatrick return true; 1495061da546Spatrick } 1496061da546Spatrick 1497061da546Spatrick bool ScriptInterpreterPythonImpl::GenerateTypeSynthClass( 1498061da546Spatrick StringList &user_input, std::string &output, const void *name_token) { 1499061da546Spatrick static uint32_t num_created_classes = 0; 1500061da546Spatrick user_input.RemoveBlankLines(); 1501061da546Spatrick int num_lines = user_input.GetSize(); 1502061da546Spatrick StreamString sstr; 1503061da546Spatrick 1504061da546Spatrick // Check to see if we have any data; if not, just return. 1505061da546Spatrick if (user_input.GetSize() == 0) 1506061da546Spatrick return false; 1507061da546Spatrick 1508061da546Spatrick // Wrap all user input into a Python class 1509061da546Spatrick 1510061da546Spatrick std::string auto_generated_class_name(GenerateUniqueName( 1511061da546Spatrick "lldb_autogen_python_type_synth_class", num_created_classes, name_token)); 1512061da546Spatrick 1513061da546Spatrick StringList auto_generated_class; 1514061da546Spatrick 1515061da546Spatrick // Create the function name & definition string. 1516061da546Spatrick 1517061da546Spatrick sstr.Printf("class %s:", auto_generated_class_name.c_str()); 1518061da546Spatrick auto_generated_class.AppendString(sstr.GetString()); 1519061da546Spatrick 1520061da546Spatrick // Wrap everything up inside the class, increasing the indentation. we don't 1521061da546Spatrick // need to play any fancy indentation tricks here because there is no 1522061da546Spatrick // surrounding code whose indentation we need to honor 1523061da546Spatrick for (int i = 0; i < num_lines; ++i) { 1524061da546Spatrick sstr.Clear(); 1525061da546Spatrick sstr.Printf(" %s", user_input.GetStringAtIndex(i)); 1526061da546Spatrick auto_generated_class.AppendString(sstr.GetString()); 1527061da546Spatrick } 1528061da546Spatrick 1529061da546Spatrick // Verify that the results are valid Python. (even though the method is 1530061da546Spatrick // ExportFunctionDefinitionToInterpreter, a class will actually be exported) 1531061da546Spatrick // (TODO: rename that method to ExportDefinitionToInterpreter) 1532061da546Spatrick if (!ExportFunctionDefinitionToInterpreter(auto_generated_class).Success()) 1533061da546Spatrick return false; 1534061da546Spatrick 1535061da546Spatrick // Store the name of the auto-generated class 1536061da546Spatrick 1537061da546Spatrick output.assign(auto_generated_class_name); 1538061da546Spatrick return true; 1539061da546Spatrick } 1540061da546Spatrick 1541061da546Spatrick StructuredData::GenericSP 1542061da546Spatrick ScriptInterpreterPythonImpl::CreateFrameRecognizer(const char *class_name) { 1543061da546Spatrick if (class_name == nullptr || class_name[0] == '\0') 1544061da546Spatrick return StructuredData::GenericSP(); 1545061da546Spatrick 1546061da546Spatrick void *ret_val; 1547061da546Spatrick 1548061da546Spatrick { 1549061da546Spatrick Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, 1550061da546Spatrick Locker::FreeLock); 1551061da546Spatrick ret_val = LLDBSWIGPython_CreateFrameRecognizer(class_name, 1552061da546Spatrick m_dictionary_name.c_str()); 1553061da546Spatrick } 1554061da546Spatrick 1555061da546Spatrick return StructuredData::GenericSP(new StructuredPythonObject(ret_val)); 1556061da546Spatrick } 1557061da546Spatrick 1558061da546Spatrick lldb::ValueObjectListSP ScriptInterpreterPythonImpl::GetRecognizedArguments( 1559061da546Spatrick const StructuredData::ObjectSP &os_plugin_object_sp, 1560061da546Spatrick lldb::StackFrameSP frame_sp) { 1561061da546Spatrick Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock); 1562061da546Spatrick 1563061da546Spatrick if (!os_plugin_object_sp) 1564061da546Spatrick return ValueObjectListSP(); 1565061da546Spatrick 1566061da546Spatrick StructuredData::Generic *generic = os_plugin_object_sp->GetAsGeneric(); 1567061da546Spatrick if (!generic) 1568061da546Spatrick return nullptr; 1569061da546Spatrick 1570061da546Spatrick PythonObject implementor(PyRefType::Borrowed, 1571061da546Spatrick (PyObject *)generic->GetValue()); 1572061da546Spatrick 1573061da546Spatrick if (!implementor.IsAllocated()) 1574061da546Spatrick return ValueObjectListSP(); 1575061da546Spatrick 1576061da546Spatrick PythonObject py_return(PyRefType::Owned, 1577061da546Spatrick (PyObject *)LLDBSwigPython_GetRecognizedArguments( 1578061da546Spatrick implementor.get(), frame_sp)); 1579061da546Spatrick 1580061da546Spatrick // if it fails, print the error but otherwise go on 1581061da546Spatrick if (PyErr_Occurred()) { 1582061da546Spatrick PyErr_Print(); 1583061da546Spatrick PyErr_Clear(); 1584061da546Spatrick } 1585061da546Spatrick if (py_return.get()) { 1586061da546Spatrick PythonList result_list(PyRefType::Borrowed, py_return.get()); 1587061da546Spatrick ValueObjectListSP result = ValueObjectListSP(new ValueObjectList()); 1588061da546Spatrick for (size_t i = 0; i < result_list.GetSize(); i++) { 1589061da546Spatrick PyObject *item = result_list.GetItemAtIndex(i).get(); 1590061da546Spatrick lldb::SBValue *sb_value_ptr = 1591061da546Spatrick (lldb::SBValue *)LLDBSWIGPython_CastPyObjectToSBValue(item); 1592061da546Spatrick auto valobj_sp = LLDBSWIGPython_GetValueObjectSPFromSBValue(sb_value_ptr); 1593061da546Spatrick if (valobj_sp) 1594061da546Spatrick result->Append(valobj_sp); 1595061da546Spatrick } 1596061da546Spatrick return result; 1597061da546Spatrick } 1598061da546Spatrick return ValueObjectListSP(); 1599061da546Spatrick } 1600061da546Spatrick 1601061da546Spatrick StructuredData::GenericSP 1602061da546Spatrick ScriptInterpreterPythonImpl::OSPlugin_CreatePluginObject( 1603061da546Spatrick const char *class_name, lldb::ProcessSP process_sp) { 1604061da546Spatrick if (class_name == nullptr || class_name[0] == '\0') 1605061da546Spatrick return StructuredData::GenericSP(); 1606061da546Spatrick 1607061da546Spatrick if (!process_sp) 1608061da546Spatrick return StructuredData::GenericSP(); 1609061da546Spatrick 1610061da546Spatrick void *ret_val; 1611061da546Spatrick 1612061da546Spatrick { 1613061da546Spatrick Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, 1614061da546Spatrick Locker::FreeLock); 1615061da546Spatrick ret_val = LLDBSWIGPythonCreateOSPlugin( 1616061da546Spatrick class_name, m_dictionary_name.c_str(), process_sp); 1617061da546Spatrick } 1618061da546Spatrick 1619061da546Spatrick return StructuredData::GenericSP(new StructuredPythonObject(ret_val)); 1620061da546Spatrick } 1621061da546Spatrick 1622061da546Spatrick StructuredData::DictionarySP ScriptInterpreterPythonImpl::OSPlugin_RegisterInfo( 1623061da546Spatrick StructuredData::ObjectSP os_plugin_object_sp) { 1624061da546Spatrick Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock); 1625061da546Spatrick 1626061da546Spatrick static char callee_name[] = "get_register_info"; 1627061da546Spatrick 1628061da546Spatrick if (!os_plugin_object_sp) 1629061da546Spatrick return StructuredData::DictionarySP(); 1630061da546Spatrick 1631061da546Spatrick StructuredData::Generic *generic = os_plugin_object_sp->GetAsGeneric(); 1632061da546Spatrick if (!generic) 1633061da546Spatrick return nullptr; 1634061da546Spatrick 1635061da546Spatrick PythonObject implementor(PyRefType::Borrowed, 1636061da546Spatrick (PyObject *)generic->GetValue()); 1637061da546Spatrick 1638061da546Spatrick if (!implementor.IsAllocated()) 1639061da546Spatrick return StructuredData::DictionarySP(); 1640061da546Spatrick 1641061da546Spatrick PythonObject pmeth(PyRefType::Owned, 1642061da546Spatrick PyObject_GetAttrString(implementor.get(), callee_name)); 1643061da546Spatrick 1644061da546Spatrick if (PyErr_Occurred()) 1645061da546Spatrick PyErr_Clear(); 1646061da546Spatrick 1647061da546Spatrick if (!pmeth.IsAllocated()) 1648061da546Spatrick return StructuredData::DictionarySP(); 1649061da546Spatrick 1650061da546Spatrick if (PyCallable_Check(pmeth.get()) == 0) { 1651061da546Spatrick if (PyErr_Occurred()) 1652061da546Spatrick PyErr_Clear(); 1653061da546Spatrick 1654061da546Spatrick return StructuredData::DictionarySP(); 1655061da546Spatrick } 1656061da546Spatrick 1657061da546Spatrick if (PyErr_Occurred()) 1658061da546Spatrick PyErr_Clear(); 1659061da546Spatrick 1660061da546Spatrick // right now we know this function exists and is callable.. 1661061da546Spatrick PythonObject py_return( 1662061da546Spatrick PyRefType::Owned, 1663061da546Spatrick PyObject_CallMethod(implementor.get(), callee_name, nullptr)); 1664061da546Spatrick 1665061da546Spatrick // if it fails, print the error but otherwise go on 1666061da546Spatrick if (PyErr_Occurred()) { 1667061da546Spatrick PyErr_Print(); 1668061da546Spatrick PyErr_Clear(); 1669061da546Spatrick } 1670061da546Spatrick if (py_return.get()) { 1671061da546Spatrick PythonDictionary result_dict(PyRefType::Borrowed, py_return.get()); 1672061da546Spatrick return result_dict.CreateStructuredDictionary(); 1673061da546Spatrick } 1674061da546Spatrick return StructuredData::DictionarySP(); 1675061da546Spatrick } 1676061da546Spatrick 1677061da546Spatrick StructuredData::ArraySP ScriptInterpreterPythonImpl::OSPlugin_ThreadsInfo( 1678061da546Spatrick StructuredData::ObjectSP os_plugin_object_sp) { 1679061da546Spatrick Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock); 1680061da546Spatrick 1681061da546Spatrick static char callee_name[] = "get_thread_info"; 1682061da546Spatrick 1683061da546Spatrick if (!os_plugin_object_sp) 1684061da546Spatrick return StructuredData::ArraySP(); 1685061da546Spatrick 1686061da546Spatrick StructuredData::Generic *generic = os_plugin_object_sp->GetAsGeneric(); 1687061da546Spatrick if (!generic) 1688061da546Spatrick return nullptr; 1689061da546Spatrick 1690061da546Spatrick PythonObject implementor(PyRefType::Borrowed, 1691061da546Spatrick (PyObject *)generic->GetValue()); 1692061da546Spatrick 1693061da546Spatrick if (!implementor.IsAllocated()) 1694061da546Spatrick return StructuredData::ArraySP(); 1695061da546Spatrick 1696061da546Spatrick PythonObject pmeth(PyRefType::Owned, 1697061da546Spatrick PyObject_GetAttrString(implementor.get(), callee_name)); 1698061da546Spatrick 1699061da546Spatrick if (PyErr_Occurred()) 1700061da546Spatrick PyErr_Clear(); 1701061da546Spatrick 1702061da546Spatrick if (!pmeth.IsAllocated()) 1703061da546Spatrick return StructuredData::ArraySP(); 1704061da546Spatrick 1705061da546Spatrick if (PyCallable_Check(pmeth.get()) == 0) { 1706061da546Spatrick if (PyErr_Occurred()) 1707061da546Spatrick PyErr_Clear(); 1708061da546Spatrick 1709061da546Spatrick return StructuredData::ArraySP(); 1710061da546Spatrick } 1711061da546Spatrick 1712061da546Spatrick if (PyErr_Occurred()) 1713061da546Spatrick PyErr_Clear(); 1714061da546Spatrick 1715061da546Spatrick // right now we know this function exists and is callable.. 1716061da546Spatrick PythonObject py_return( 1717061da546Spatrick PyRefType::Owned, 1718061da546Spatrick PyObject_CallMethod(implementor.get(), callee_name, nullptr)); 1719061da546Spatrick 1720061da546Spatrick // if it fails, print the error but otherwise go on 1721061da546Spatrick if (PyErr_Occurred()) { 1722061da546Spatrick PyErr_Print(); 1723061da546Spatrick PyErr_Clear(); 1724061da546Spatrick } 1725061da546Spatrick 1726061da546Spatrick if (py_return.get()) { 1727061da546Spatrick PythonList result_list(PyRefType::Borrowed, py_return.get()); 1728061da546Spatrick return result_list.CreateStructuredArray(); 1729061da546Spatrick } 1730061da546Spatrick return StructuredData::ArraySP(); 1731061da546Spatrick } 1732061da546Spatrick 1733061da546Spatrick StructuredData::StringSP 1734061da546Spatrick ScriptInterpreterPythonImpl::OSPlugin_RegisterContextData( 1735061da546Spatrick StructuredData::ObjectSP os_plugin_object_sp, lldb::tid_t tid) { 1736061da546Spatrick Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock); 1737061da546Spatrick 1738061da546Spatrick static char callee_name[] = "get_register_data"; 1739061da546Spatrick static char *param_format = 1740061da546Spatrick const_cast<char *>(GetPythonValueFormatString(tid)); 1741061da546Spatrick 1742061da546Spatrick if (!os_plugin_object_sp) 1743061da546Spatrick return StructuredData::StringSP(); 1744061da546Spatrick 1745061da546Spatrick StructuredData::Generic *generic = os_plugin_object_sp->GetAsGeneric(); 1746061da546Spatrick if (!generic) 1747061da546Spatrick return nullptr; 1748061da546Spatrick PythonObject implementor(PyRefType::Borrowed, 1749061da546Spatrick (PyObject *)generic->GetValue()); 1750061da546Spatrick 1751061da546Spatrick if (!implementor.IsAllocated()) 1752061da546Spatrick return StructuredData::StringSP(); 1753061da546Spatrick 1754061da546Spatrick PythonObject pmeth(PyRefType::Owned, 1755061da546Spatrick PyObject_GetAttrString(implementor.get(), callee_name)); 1756061da546Spatrick 1757061da546Spatrick if (PyErr_Occurred()) 1758061da546Spatrick PyErr_Clear(); 1759061da546Spatrick 1760061da546Spatrick if (!pmeth.IsAllocated()) 1761061da546Spatrick return StructuredData::StringSP(); 1762061da546Spatrick 1763061da546Spatrick if (PyCallable_Check(pmeth.get()) == 0) { 1764061da546Spatrick if (PyErr_Occurred()) 1765061da546Spatrick PyErr_Clear(); 1766061da546Spatrick return StructuredData::StringSP(); 1767061da546Spatrick } 1768061da546Spatrick 1769061da546Spatrick if (PyErr_Occurred()) 1770061da546Spatrick PyErr_Clear(); 1771061da546Spatrick 1772061da546Spatrick // right now we know this function exists and is callable.. 1773061da546Spatrick PythonObject py_return( 1774061da546Spatrick PyRefType::Owned, 1775061da546Spatrick PyObject_CallMethod(implementor.get(), callee_name, param_format, tid)); 1776061da546Spatrick 1777061da546Spatrick // if it fails, print the error but otherwise go on 1778061da546Spatrick if (PyErr_Occurred()) { 1779061da546Spatrick PyErr_Print(); 1780061da546Spatrick PyErr_Clear(); 1781061da546Spatrick } 1782061da546Spatrick 1783061da546Spatrick if (py_return.get()) { 1784061da546Spatrick PythonBytes result(PyRefType::Borrowed, py_return.get()); 1785061da546Spatrick return result.CreateStructuredString(); 1786061da546Spatrick } 1787061da546Spatrick return StructuredData::StringSP(); 1788061da546Spatrick } 1789061da546Spatrick 1790061da546Spatrick StructuredData::DictionarySP ScriptInterpreterPythonImpl::OSPlugin_CreateThread( 1791061da546Spatrick StructuredData::ObjectSP os_plugin_object_sp, lldb::tid_t tid, 1792061da546Spatrick lldb::addr_t context) { 1793061da546Spatrick Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock); 1794061da546Spatrick 1795061da546Spatrick static char callee_name[] = "create_thread"; 1796061da546Spatrick std::string param_format; 1797061da546Spatrick param_format += GetPythonValueFormatString(tid); 1798061da546Spatrick param_format += GetPythonValueFormatString(context); 1799061da546Spatrick 1800061da546Spatrick if (!os_plugin_object_sp) 1801061da546Spatrick return StructuredData::DictionarySP(); 1802061da546Spatrick 1803061da546Spatrick StructuredData::Generic *generic = os_plugin_object_sp->GetAsGeneric(); 1804061da546Spatrick if (!generic) 1805061da546Spatrick return nullptr; 1806061da546Spatrick 1807061da546Spatrick PythonObject implementor(PyRefType::Borrowed, 1808061da546Spatrick (PyObject *)generic->GetValue()); 1809061da546Spatrick 1810061da546Spatrick if (!implementor.IsAllocated()) 1811061da546Spatrick return StructuredData::DictionarySP(); 1812061da546Spatrick 1813061da546Spatrick PythonObject pmeth(PyRefType::Owned, 1814061da546Spatrick PyObject_GetAttrString(implementor.get(), callee_name)); 1815061da546Spatrick 1816061da546Spatrick if (PyErr_Occurred()) 1817061da546Spatrick PyErr_Clear(); 1818061da546Spatrick 1819061da546Spatrick if (!pmeth.IsAllocated()) 1820061da546Spatrick return StructuredData::DictionarySP(); 1821061da546Spatrick 1822061da546Spatrick if (PyCallable_Check(pmeth.get()) == 0) { 1823061da546Spatrick if (PyErr_Occurred()) 1824061da546Spatrick PyErr_Clear(); 1825061da546Spatrick return StructuredData::DictionarySP(); 1826061da546Spatrick } 1827061da546Spatrick 1828061da546Spatrick if (PyErr_Occurred()) 1829061da546Spatrick PyErr_Clear(); 1830061da546Spatrick 1831061da546Spatrick // right now we know this function exists and is callable.. 1832061da546Spatrick PythonObject py_return(PyRefType::Owned, 1833061da546Spatrick PyObject_CallMethod(implementor.get(), callee_name, 1834061da546Spatrick ¶m_format[0], tid, context)); 1835061da546Spatrick 1836061da546Spatrick // if it fails, print the error but otherwise go on 1837061da546Spatrick if (PyErr_Occurred()) { 1838061da546Spatrick PyErr_Print(); 1839061da546Spatrick PyErr_Clear(); 1840061da546Spatrick } 1841061da546Spatrick 1842061da546Spatrick if (py_return.get()) { 1843061da546Spatrick PythonDictionary result_dict(PyRefType::Borrowed, py_return.get()); 1844061da546Spatrick return result_dict.CreateStructuredDictionary(); 1845061da546Spatrick } 1846061da546Spatrick return StructuredData::DictionarySP(); 1847061da546Spatrick } 1848061da546Spatrick 1849061da546Spatrick StructuredData::ObjectSP ScriptInterpreterPythonImpl::CreateScriptedThreadPlan( 1850061da546Spatrick const char *class_name, StructuredDataImpl *args_data, 1851061da546Spatrick std::string &error_str, lldb::ThreadPlanSP thread_plan_sp) { 1852061da546Spatrick if (class_name == nullptr || class_name[0] == '\0') 1853061da546Spatrick return StructuredData::ObjectSP(); 1854061da546Spatrick 1855061da546Spatrick if (!thread_plan_sp.get()) 1856061da546Spatrick return {}; 1857061da546Spatrick 1858061da546Spatrick Debugger &debugger = thread_plan_sp->GetTarget().GetDebugger(); 1859061da546Spatrick ScriptInterpreterPythonImpl *python_interpreter = 1860*be691f3bSpatrick GetPythonInterpreter(debugger); 1861061da546Spatrick 1862*be691f3bSpatrick if (!python_interpreter) 1863061da546Spatrick return {}; 1864061da546Spatrick 1865061da546Spatrick void *ret_val; 1866061da546Spatrick 1867061da546Spatrick { 1868061da546Spatrick Locker py_lock(this, 1869061da546Spatrick Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); 1870061da546Spatrick ret_val = LLDBSwigPythonCreateScriptedThreadPlan( 1871061da546Spatrick class_name, python_interpreter->m_dictionary_name.c_str(), 1872061da546Spatrick args_data, error_str, thread_plan_sp); 1873061da546Spatrick if (!ret_val) 1874061da546Spatrick return {}; 1875061da546Spatrick } 1876061da546Spatrick 1877061da546Spatrick return StructuredData::ObjectSP(new StructuredPythonObject(ret_val)); 1878061da546Spatrick } 1879061da546Spatrick 1880061da546Spatrick bool ScriptInterpreterPythonImpl::ScriptedThreadPlanExplainsStop( 1881061da546Spatrick StructuredData::ObjectSP implementor_sp, Event *event, bool &script_error) { 1882061da546Spatrick bool explains_stop = true; 1883061da546Spatrick StructuredData::Generic *generic = nullptr; 1884061da546Spatrick if (implementor_sp) 1885061da546Spatrick generic = implementor_sp->GetAsGeneric(); 1886061da546Spatrick if (generic) { 1887061da546Spatrick Locker py_lock(this, 1888061da546Spatrick Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); 1889061da546Spatrick explains_stop = LLDBSWIGPythonCallThreadPlan( 1890061da546Spatrick generic->GetValue(), "explains_stop", event, script_error); 1891061da546Spatrick if (script_error) 1892061da546Spatrick return true; 1893061da546Spatrick } 1894061da546Spatrick return explains_stop; 1895061da546Spatrick } 1896061da546Spatrick 1897061da546Spatrick bool ScriptInterpreterPythonImpl::ScriptedThreadPlanShouldStop( 1898061da546Spatrick StructuredData::ObjectSP implementor_sp, Event *event, bool &script_error) { 1899061da546Spatrick bool should_stop = true; 1900061da546Spatrick StructuredData::Generic *generic = nullptr; 1901061da546Spatrick if (implementor_sp) 1902061da546Spatrick generic = implementor_sp->GetAsGeneric(); 1903061da546Spatrick if (generic) { 1904061da546Spatrick Locker py_lock(this, 1905061da546Spatrick Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); 1906061da546Spatrick should_stop = LLDBSWIGPythonCallThreadPlan( 1907061da546Spatrick generic->GetValue(), "should_stop", event, script_error); 1908061da546Spatrick if (script_error) 1909061da546Spatrick return true; 1910061da546Spatrick } 1911061da546Spatrick return should_stop; 1912061da546Spatrick } 1913061da546Spatrick 1914061da546Spatrick bool ScriptInterpreterPythonImpl::ScriptedThreadPlanIsStale( 1915061da546Spatrick StructuredData::ObjectSP implementor_sp, bool &script_error) { 1916061da546Spatrick bool is_stale = true; 1917061da546Spatrick StructuredData::Generic *generic = nullptr; 1918061da546Spatrick if (implementor_sp) 1919061da546Spatrick generic = implementor_sp->GetAsGeneric(); 1920061da546Spatrick if (generic) { 1921061da546Spatrick Locker py_lock(this, 1922061da546Spatrick Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); 1923061da546Spatrick is_stale = LLDBSWIGPythonCallThreadPlan(generic->GetValue(), "is_stale", 1924061da546Spatrick nullptr, script_error); 1925061da546Spatrick if (script_error) 1926061da546Spatrick return true; 1927061da546Spatrick } 1928061da546Spatrick return is_stale; 1929061da546Spatrick } 1930061da546Spatrick 1931061da546Spatrick lldb::StateType ScriptInterpreterPythonImpl::ScriptedThreadPlanGetRunState( 1932061da546Spatrick StructuredData::ObjectSP implementor_sp, bool &script_error) { 1933061da546Spatrick bool should_step = false; 1934061da546Spatrick StructuredData::Generic *generic = nullptr; 1935061da546Spatrick if (implementor_sp) 1936061da546Spatrick generic = implementor_sp->GetAsGeneric(); 1937061da546Spatrick if (generic) { 1938061da546Spatrick Locker py_lock(this, 1939061da546Spatrick Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); 1940061da546Spatrick should_step = LLDBSWIGPythonCallThreadPlan( 1941061da546Spatrick generic->GetValue(), "should_step", nullptr, script_error); 1942061da546Spatrick if (script_error) 1943061da546Spatrick should_step = true; 1944061da546Spatrick } 1945061da546Spatrick if (should_step) 1946061da546Spatrick return lldb::eStateStepping; 1947061da546Spatrick return lldb::eStateRunning; 1948061da546Spatrick } 1949061da546Spatrick 1950061da546Spatrick StructuredData::GenericSP 1951061da546Spatrick ScriptInterpreterPythonImpl::CreateScriptedBreakpointResolver( 1952061da546Spatrick const char *class_name, StructuredDataImpl *args_data, 1953061da546Spatrick lldb::BreakpointSP &bkpt_sp) { 1954061da546Spatrick 1955061da546Spatrick if (class_name == nullptr || class_name[0] == '\0') 1956061da546Spatrick return StructuredData::GenericSP(); 1957061da546Spatrick 1958061da546Spatrick if (!bkpt_sp.get()) 1959061da546Spatrick return StructuredData::GenericSP(); 1960061da546Spatrick 1961061da546Spatrick Debugger &debugger = bkpt_sp->GetTarget().GetDebugger(); 1962061da546Spatrick ScriptInterpreterPythonImpl *python_interpreter = 1963*be691f3bSpatrick GetPythonInterpreter(debugger); 1964061da546Spatrick 1965*be691f3bSpatrick if (!python_interpreter) 1966061da546Spatrick return StructuredData::GenericSP(); 1967061da546Spatrick 1968061da546Spatrick void *ret_val; 1969061da546Spatrick 1970061da546Spatrick { 1971061da546Spatrick Locker py_lock(this, 1972061da546Spatrick Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); 1973061da546Spatrick 1974061da546Spatrick ret_val = LLDBSwigPythonCreateScriptedBreakpointResolver( 1975061da546Spatrick class_name, python_interpreter->m_dictionary_name.c_str(), args_data, 1976061da546Spatrick bkpt_sp); 1977061da546Spatrick } 1978061da546Spatrick 1979061da546Spatrick return StructuredData::GenericSP(new StructuredPythonObject(ret_val)); 1980061da546Spatrick } 1981061da546Spatrick 1982061da546Spatrick bool ScriptInterpreterPythonImpl::ScriptedBreakpointResolverSearchCallback( 1983061da546Spatrick StructuredData::GenericSP implementor_sp, SymbolContext *sym_ctx) { 1984061da546Spatrick bool should_continue = false; 1985061da546Spatrick 1986061da546Spatrick if (implementor_sp) { 1987061da546Spatrick Locker py_lock(this, 1988061da546Spatrick Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); 1989061da546Spatrick should_continue = LLDBSwigPythonCallBreakpointResolver( 1990061da546Spatrick implementor_sp->GetValue(), "__callback__", sym_ctx); 1991061da546Spatrick if (PyErr_Occurred()) { 1992061da546Spatrick PyErr_Print(); 1993061da546Spatrick PyErr_Clear(); 1994061da546Spatrick } 1995061da546Spatrick } 1996061da546Spatrick return should_continue; 1997061da546Spatrick } 1998061da546Spatrick 1999061da546Spatrick lldb::SearchDepth 2000061da546Spatrick ScriptInterpreterPythonImpl::ScriptedBreakpointResolverSearchDepth( 2001061da546Spatrick StructuredData::GenericSP implementor_sp) { 2002061da546Spatrick int depth_as_int = lldb::eSearchDepthModule; 2003061da546Spatrick if (implementor_sp) { 2004061da546Spatrick Locker py_lock(this, 2005061da546Spatrick Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); 2006061da546Spatrick depth_as_int = LLDBSwigPythonCallBreakpointResolver( 2007061da546Spatrick implementor_sp->GetValue(), "__get_depth__", nullptr); 2008061da546Spatrick if (PyErr_Occurred()) { 2009061da546Spatrick PyErr_Print(); 2010061da546Spatrick PyErr_Clear(); 2011061da546Spatrick } 2012061da546Spatrick } 2013061da546Spatrick if (depth_as_int == lldb::eSearchDepthInvalid) 2014061da546Spatrick return lldb::eSearchDepthModule; 2015061da546Spatrick 2016061da546Spatrick if (depth_as_int <= lldb::kLastSearchDepthKind) 2017061da546Spatrick return (lldb::SearchDepth)depth_as_int; 2018061da546Spatrick return lldb::eSearchDepthModule; 2019061da546Spatrick } 2020061da546Spatrick 2021*be691f3bSpatrick StructuredData::GenericSP ScriptInterpreterPythonImpl::CreateScriptedStopHook( 2022*be691f3bSpatrick TargetSP target_sp, const char *class_name, StructuredDataImpl *args_data, 2023*be691f3bSpatrick Status &error) { 2024*be691f3bSpatrick 2025*be691f3bSpatrick if (!target_sp) { 2026*be691f3bSpatrick error.SetErrorString("No target for scripted stop-hook."); 2027*be691f3bSpatrick return StructuredData::GenericSP(); 2028*be691f3bSpatrick } 2029*be691f3bSpatrick 2030*be691f3bSpatrick if (class_name == nullptr || class_name[0] == '\0') { 2031*be691f3bSpatrick error.SetErrorString("No class name for scripted stop-hook."); 2032*be691f3bSpatrick return StructuredData::GenericSP(); 2033*be691f3bSpatrick } 2034*be691f3bSpatrick 2035*be691f3bSpatrick ScriptInterpreterPythonImpl *python_interpreter = 2036*be691f3bSpatrick GetPythonInterpreter(m_debugger); 2037*be691f3bSpatrick 2038*be691f3bSpatrick if (!python_interpreter) { 2039*be691f3bSpatrick error.SetErrorString("No script interpreter for scripted stop-hook."); 2040*be691f3bSpatrick return StructuredData::GenericSP(); 2041*be691f3bSpatrick } 2042*be691f3bSpatrick 2043*be691f3bSpatrick void *ret_val; 2044*be691f3bSpatrick 2045*be691f3bSpatrick { 2046*be691f3bSpatrick Locker py_lock(this, 2047*be691f3bSpatrick Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); 2048*be691f3bSpatrick 2049*be691f3bSpatrick ret_val = LLDBSwigPythonCreateScriptedStopHook( 2050*be691f3bSpatrick target_sp, class_name, python_interpreter->m_dictionary_name.c_str(), 2051*be691f3bSpatrick args_data, error); 2052*be691f3bSpatrick } 2053*be691f3bSpatrick 2054*be691f3bSpatrick return StructuredData::GenericSP(new StructuredPythonObject(ret_val)); 2055*be691f3bSpatrick } 2056*be691f3bSpatrick 2057*be691f3bSpatrick bool ScriptInterpreterPythonImpl::ScriptedStopHookHandleStop( 2058*be691f3bSpatrick StructuredData::GenericSP implementor_sp, ExecutionContext &exc_ctx, 2059*be691f3bSpatrick lldb::StreamSP stream_sp) { 2060*be691f3bSpatrick assert(implementor_sp && 2061*be691f3bSpatrick "can't call a stop hook with an invalid implementor"); 2062*be691f3bSpatrick assert(stream_sp && "can't call a stop hook with an invalid stream"); 2063*be691f3bSpatrick 2064*be691f3bSpatrick Locker py_lock(this, 2065*be691f3bSpatrick Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); 2066*be691f3bSpatrick 2067*be691f3bSpatrick lldb::ExecutionContextRefSP exc_ctx_ref_sp(new ExecutionContextRef(exc_ctx)); 2068*be691f3bSpatrick 2069*be691f3bSpatrick bool ret_val = LLDBSwigPythonStopHookCallHandleStop( 2070*be691f3bSpatrick implementor_sp->GetValue(), exc_ctx_ref_sp, stream_sp); 2071*be691f3bSpatrick return ret_val; 2072*be691f3bSpatrick } 2073*be691f3bSpatrick 2074061da546Spatrick StructuredData::ObjectSP 2075061da546Spatrick ScriptInterpreterPythonImpl::LoadPluginModule(const FileSpec &file_spec, 2076061da546Spatrick lldb_private::Status &error) { 2077061da546Spatrick if (!FileSystem::Instance().Exists(file_spec)) { 2078061da546Spatrick error.SetErrorString("no such file"); 2079061da546Spatrick return StructuredData::ObjectSP(); 2080061da546Spatrick } 2081061da546Spatrick 2082061da546Spatrick StructuredData::ObjectSP module_sp; 2083061da546Spatrick 2084*be691f3bSpatrick LoadScriptOptions load_script_options = 2085*be691f3bSpatrick LoadScriptOptions().SetInitSession(true).SetSilent(false); 2086*be691f3bSpatrick if (LoadScriptingModule(file_spec.GetPath().c_str(), load_script_options, 2087*be691f3bSpatrick error, &module_sp)) 2088061da546Spatrick return module_sp; 2089061da546Spatrick 2090061da546Spatrick return StructuredData::ObjectSP(); 2091061da546Spatrick } 2092061da546Spatrick 2093061da546Spatrick StructuredData::DictionarySP ScriptInterpreterPythonImpl::GetDynamicSettings( 2094061da546Spatrick StructuredData::ObjectSP plugin_module_sp, Target *target, 2095061da546Spatrick const char *setting_name, lldb_private::Status &error) { 2096061da546Spatrick if (!plugin_module_sp || !target || !setting_name || !setting_name[0]) 2097061da546Spatrick return StructuredData::DictionarySP(); 2098061da546Spatrick StructuredData::Generic *generic = plugin_module_sp->GetAsGeneric(); 2099061da546Spatrick if (!generic) 2100061da546Spatrick return StructuredData::DictionarySP(); 2101061da546Spatrick 2102061da546Spatrick Locker py_lock(this, 2103061da546Spatrick Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); 2104061da546Spatrick TargetSP target_sp(target->shared_from_this()); 2105061da546Spatrick 2106061da546Spatrick auto setting = (PyObject *)LLDBSWIGPython_GetDynamicSetting( 2107061da546Spatrick generic->GetValue(), setting_name, target_sp); 2108061da546Spatrick 2109061da546Spatrick if (!setting) 2110061da546Spatrick return StructuredData::DictionarySP(); 2111061da546Spatrick 2112061da546Spatrick PythonDictionary py_dict = 2113061da546Spatrick unwrapIgnoringErrors(As<PythonDictionary>(Take<PythonObject>(setting))); 2114061da546Spatrick 2115061da546Spatrick if (!py_dict) 2116061da546Spatrick return StructuredData::DictionarySP(); 2117061da546Spatrick 2118061da546Spatrick return py_dict.CreateStructuredDictionary(); 2119061da546Spatrick } 2120061da546Spatrick 2121061da546Spatrick StructuredData::ObjectSP 2122061da546Spatrick ScriptInterpreterPythonImpl::CreateSyntheticScriptedProvider( 2123061da546Spatrick const char *class_name, lldb::ValueObjectSP valobj) { 2124061da546Spatrick if (class_name == nullptr || class_name[0] == '\0') 2125061da546Spatrick return StructuredData::ObjectSP(); 2126061da546Spatrick 2127061da546Spatrick if (!valobj.get()) 2128061da546Spatrick return StructuredData::ObjectSP(); 2129061da546Spatrick 2130061da546Spatrick ExecutionContext exe_ctx(valobj->GetExecutionContextRef()); 2131061da546Spatrick Target *target = exe_ctx.GetTargetPtr(); 2132061da546Spatrick 2133061da546Spatrick if (!target) 2134061da546Spatrick return StructuredData::ObjectSP(); 2135061da546Spatrick 2136061da546Spatrick Debugger &debugger = target->GetDebugger(); 2137061da546Spatrick ScriptInterpreterPythonImpl *python_interpreter = 2138*be691f3bSpatrick GetPythonInterpreter(debugger); 2139061da546Spatrick 2140*be691f3bSpatrick if (!python_interpreter) 2141061da546Spatrick return StructuredData::ObjectSP(); 2142061da546Spatrick 2143061da546Spatrick void *ret_val = nullptr; 2144061da546Spatrick 2145061da546Spatrick { 2146061da546Spatrick Locker py_lock(this, 2147061da546Spatrick Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); 2148061da546Spatrick ret_val = LLDBSwigPythonCreateSyntheticProvider( 2149061da546Spatrick class_name, python_interpreter->m_dictionary_name.c_str(), valobj); 2150061da546Spatrick } 2151061da546Spatrick 2152061da546Spatrick return StructuredData::ObjectSP(new StructuredPythonObject(ret_val)); 2153061da546Spatrick } 2154061da546Spatrick 2155061da546Spatrick StructuredData::GenericSP 2156061da546Spatrick ScriptInterpreterPythonImpl::CreateScriptCommandObject(const char *class_name) { 2157061da546Spatrick DebuggerSP debugger_sp(m_debugger.shared_from_this()); 2158061da546Spatrick 2159061da546Spatrick if (class_name == nullptr || class_name[0] == '\0') 2160061da546Spatrick return StructuredData::GenericSP(); 2161061da546Spatrick 2162061da546Spatrick if (!debugger_sp.get()) 2163061da546Spatrick return StructuredData::GenericSP(); 2164061da546Spatrick 2165061da546Spatrick void *ret_val; 2166061da546Spatrick 2167061da546Spatrick { 2168061da546Spatrick Locker py_lock(this, 2169061da546Spatrick Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); 2170061da546Spatrick ret_val = LLDBSwigPythonCreateCommandObject( 2171061da546Spatrick class_name, m_dictionary_name.c_str(), debugger_sp); 2172061da546Spatrick } 2173061da546Spatrick 2174061da546Spatrick return StructuredData::GenericSP(new StructuredPythonObject(ret_val)); 2175061da546Spatrick } 2176061da546Spatrick 2177061da546Spatrick bool ScriptInterpreterPythonImpl::GenerateTypeScriptFunction( 2178061da546Spatrick const char *oneliner, std::string &output, const void *name_token) { 2179061da546Spatrick StringList input; 2180061da546Spatrick input.SplitIntoLines(oneliner, strlen(oneliner)); 2181061da546Spatrick return GenerateTypeScriptFunction(input, output, name_token); 2182061da546Spatrick } 2183061da546Spatrick 2184061da546Spatrick bool ScriptInterpreterPythonImpl::GenerateTypeSynthClass( 2185061da546Spatrick const char *oneliner, std::string &output, const void *name_token) { 2186061da546Spatrick StringList input; 2187061da546Spatrick input.SplitIntoLines(oneliner, strlen(oneliner)); 2188061da546Spatrick return GenerateTypeSynthClass(input, output, name_token); 2189061da546Spatrick } 2190061da546Spatrick 2191061da546Spatrick Status ScriptInterpreterPythonImpl::GenerateBreakpointCommandCallbackData( 2192061da546Spatrick StringList &user_input, std::string &output, 2193061da546Spatrick bool has_extra_args) { 2194061da546Spatrick static uint32_t num_created_functions = 0; 2195061da546Spatrick user_input.RemoveBlankLines(); 2196061da546Spatrick StreamString sstr; 2197061da546Spatrick Status error; 2198061da546Spatrick if (user_input.GetSize() == 0) { 2199061da546Spatrick error.SetErrorString("No input data."); 2200061da546Spatrick return error; 2201061da546Spatrick } 2202061da546Spatrick 2203061da546Spatrick std::string auto_generated_function_name(GenerateUniqueName( 2204061da546Spatrick "lldb_autogen_python_bp_callback_func_", num_created_functions)); 2205061da546Spatrick if (has_extra_args) 2206061da546Spatrick sstr.Printf("def %s (frame, bp_loc, extra_args, internal_dict):", 2207061da546Spatrick auto_generated_function_name.c_str()); 2208061da546Spatrick else 2209061da546Spatrick sstr.Printf("def %s (frame, bp_loc, internal_dict):", 2210061da546Spatrick auto_generated_function_name.c_str()); 2211061da546Spatrick 2212061da546Spatrick error = GenerateFunction(sstr.GetData(), user_input); 2213061da546Spatrick if (!error.Success()) 2214061da546Spatrick return error; 2215061da546Spatrick 2216061da546Spatrick // Store the name of the auto-generated function to be called. 2217061da546Spatrick output.assign(auto_generated_function_name); 2218061da546Spatrick return error; 2219061da546Spatrick } 2220061da546Spatrick 2221061da546Spatrick bool ScriptInterpreterPythonImpl::GenerateWatchpointCommandCallbackData( 2222061da546Spatrick StringList &user_input, std::string &output) { 2223061da546Spatrick static uint32_t num_created_functions = 0; 2224061da546Spatrick user_input.RemoveBlankLines(); 2225061da546Spatrick StreamString sstr; 2226061da546Spatrick 2227061da546Spatrick if (user_input.GetSize() == 0) 2228061da546Spatrick return false; 2229061da546Spatrick 2230061da546Spatrick std::string auto_generated_function_name(GenerateUniqueName( 2231061da546Spatrick "lldb_autogen_python_wp_callback_func_", num_created_functions)); 2232061da546Spatrick sstr.Printf("def %s (frame, wp, internal_dict):", 2233061da546Spatrick auto_generated_function_name.c_str()); 2234061da546Spatrick 2235061da546Spatrick if (!GenerateFunction(sstr.GetData(), user_input).Success()) 2236061da546Spatrick return false; 2237061da546Spatrick 2238061da546Spatrick // Store the name of the auto-generated function to be called. 2239061da546Spatrick output.assign(auto_generated_function_name); 2240061da546Spatrick return true; 2241061da546Spatrick } 2242061da546Spatrick 2243061da546Spatrick bool ScriptInterpreterPythonImpl::GetScriptedSummary( 2244061da546Spatrick const char *python_function_name, lldb::ValueObjectSP valobj, 2245061da546Spatrick StructuredData::ObjectSP &callee_wrapper_sp, 2246061da546Spatrick const TypeSummaryOptions &options, std::string &retval) { 2247061da546Spatrick 2248*be691f3bSpatrick LLDB_SCOPED_TIMER(); 2249061da546Spatrick 2250061da546Spatrick if (!valobj.get()) { 2251061da546Spatrick retval.assign("<no object>"); 2252061da546Spatrick return false; 2253061da546Spatrick } 2254061da546Spatrick 2255061da546Spatrick void *old_callee = nullptr; 2256061da546Spatrick StructuredData::Generic *generic = nullptr; 2257061da546Spatrick if (callee_wrapper_sp) { 2258061da546Spatrick generic = callee_wrapper_sp->GetAsGeneric(); 2259061da546Spatrick if (generic) 2260061da546Spatrick old_callee = generic->GetValue(); 2261061da546Spatrick } 2262061da546Spatrick void *new_callee = old_callee; 2263061da546Spatrick 2264061da546Spatrick bool ret_val; 2265061da546Spatrick if (python_function_name && *python_function_name) { 2266061da546Spatrick { 2267061da546Spatrick Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | 2268061da546Spatrick Locker::NoSTDIN); 2269061da546Spatrick { 2270061da546Spatrick TypeSummaryOptionsSP options_sp(new TypeSummaryOptions(options)); 2271061da546Spatrick 2272061da546Spatrick static Timer::Category func_cat("LLDBSwigPythonCallTypeScript"); 2273061da546Spatrick Timer scoped_timer(func_cat, "LLDBSwigPythonCallTypeScript"); 2274061da546Spatrick ret_val = LLDBSwigPythonCallTypeScript( 2275061da546Spatrick python_function_name, GetSessionDictionary().get(), valobj, 2276061da546Spatrick &new_callee, options_sp, retval); 2277061da546Spatrick } 2278061da546Spatrick } 2279061da546Spatrick } else { 2280061da546Spatrick retval.assign("<no function name>"); 2281061da546Spatrick return false; 2282061da546Spatrick } 2283061da546Spatrick 2284061da546Spatrick if (new_callee && old_callee != new_callee) 2285061da546Spatrick callee_wrapper_sp = std::make_shared<StructuredPythonObject>(new_callee); 2286061da546Spatrick 2287061da546Spatrick return ret_val; 2288061da546Spatrick } 2289061da546Spatrick 2290061da546Spatrick bool ScriptInterpreterPythonImpl::BreakpointCallbackFunction( 2291061da546Spatrick void *baton, StoppointCallbackContext *context, user_id_t break_id, 2292061da546Spatrick user_id_t break_loc_id) { 2293061da546Spatrick CommandDataPython *bp_option_data = (CommandDataPython *)baton; 2294061da546Spatrick const char *python_function_name = bp_option_data->script_source.c_str(); 2295061da546Spatrick 2296061da546Spatrick if (!context) 2297061da546Spatrick return true; 2298061da546Spatrick 2299061da546Spatrick ExecutionContext exe_ctx(context->exe_ctx_ref); 2300061da546Spatrick Target *target = exe_ctx.GetTargetPtr(); 2301061da546Spatrick 2302061da546Spatrick if (!target) 2303061da546Spatrick return true; 2304061da546Spatrick 2305061da546Spatrick Debugger &debugger = target->GetDebugger(); 2306061da546Spatrick ScriptInterpreterPythonImpl *python_interpreter = 2307*be691f3bSpatrick GetPythonInterpreter(debugger); 2308061da546Spatrick 2309*be691f3bSpatrick if (!python_interpreter) 2310061da546Spatrick return true; 2311061da546Spatrick 2312061da546Spatrick if (python_function_name && python_function_name[0]) { 2313061da546Spatrick const StackFrameSP stop_frame_sp(exe_ctx.GetFrameSP()); 2314061da546Spatrick BreakpointSP breakpoint_sp = target->GetBreakpointByID(break_id); 2315061da546Spatrick if (breakpoint_sp) { 2316061da546Spatrick const BreakpointLocationSP bp_loc_sp( 2317061da546Spatrick breakpoint_sp->FindLocationByID(break_loc_id)); 2318061da546Spatrick 2319061da546Spatrick if (stop_frame_sp && bp_loc_sp) { 2320061da546Spatrick bool ret_val = true; 2321061da546Spatrick { 2322061da546Spatrick Locker py_lock(python_interpreter, Locker::AcquireLock | 2323061da546Spatrick Locker::InitSession | 2324061da546Spatrick Locker::NoSTDIN); 2325061da546Spatrick Expected<bool> maybe_ret_val = 2326061da546Spatrick LLDBSwigPythonBreakpointCallbackFunction( 2327061da546Spatrick python_function_name, 2328061da546Spatrick python_interpreter->m_dictionary_name.c_str(), stop_frame_sp, 2329061da546Spatrick bp_loc_sp, bp_option_data->m_extra_args_up.get()); 2330061da546Spatrick 2331061da546Spatrick if (!maybe_ret_val) { 2332061da546Spatrick 2333061da546Spatrick llvm::handleAllErrors( 2334061da546Spatrick maybe_ret_val.takeError(), 2335061da546Spatrick [&](PythonException &E) { 2336061da546Spatrick debugger.GetErrorStream() << E.ReadBacktrace(); 2337061da546Spatrick }, 2338061da546Spatrick [&](const llvm::ErrorInfoBase &E) { 2339061da546Spatrick debugger.GetErrorStream() << E.message(); 2340061da546Spatrick }); 2341061da546Spatrick 2342061da546Spatrick } else { 2343061da546Spatrick ret_val = maybe_ret_val.get(); 2344061da546Spatrick } 2345061da546Spatrick } 2346061da546Spatrick return ret_val; 2347061da546Spatrick } 2348061da546Spatrick } 2349061da546Spatrick } 2350061da546Spatrick // We currently always true so we stop in case anything goes wrong when 2351061da546Spatrick // trying to call the script function 2352061da546Spatrick return true; 2353061da546Spatrick } 2354061da546Spatrick 2355061da546Spatrick bool ScriptInterpreterPythonImpl::WatchpointCallbackFunction( 2356061da546Spatrick void *baton, StoppointCallbackContext *context, user_id_t watch_id) { 2357061da546Spatrick WatchpointOptions::CommandData *wp_option_data = 2358061da546Spatrick (WatchpointOptions::CommandData *)baton; 2359061da546Spatrick const char *python_function_name = wp_option_data->script_source.c_str(); 2360061da546Spatrick 2361061da546Spatrick if (!context) 2362061da546Spatrick return true; 2363061da546Spatrick 2364061da546Spatrick ExecutionContext exe_ctx(context->exe_ctx_ref); 2365061da546Spatrick Target *target = exe_ctx.GetTargetPtr(); 2366061da546Spatrick 2367061da546Spatrick if (!target) 2368061da546Spatrick return true; 2369061da546Spatrick 2370061da546Spatrick Debugger &debugger = target->GetDebugger(); 2371061da546Spatrick ScriptInterpreterPythonImpl *python_interpreter = 2372*be691f3bSpatrick GetPythonInterpreter(debugger); 2373061da546Spatrick 2374*be691f3bSpatrick if (!python_interpreter) 2375061da546Spatrick return true; 2376061da546Spatrick 2377061da546Spatrick if (python_function_name && python_function_name[0]) { 2378061da546Spatrick const StackFrameSP stop_frame_sp(exe_ctx.GetFrameSP()); 2379061da546Spatrick WatchpointSP wp_sp = target->GetWatchpointList().FindByID(watch_id); 2380061da546Spatrick if (wp_sp) { 2381061da546Spatrick if (stop_frame_sp && wp_sp) { 2382061da546Spatrick bool ret_val = true; 2383061da546Spatrick { 2384061da546Spatrick Locker py_lock(python_interpreter, Locker::AcquireLock | 2385061da546Spatrick Locker::InitSession | 2386061da546Spatrick Locker::NoSTDIN); 2387061da546Spatrick ret_val = LLDBSwigPythonWatchpointCallbackFunction( 2388061da546Spatrick python_function_name, 2389061da546Spatrick python_interpreter->m_dictionary_name.c_str(), stop_frame_sp, 2390061da546Spatrick wp_sp); 2391061da546Spatrick } 2392061da546Spatrick return ret_val; 2393061da546Spatrick } 2394061da546Spatrick } 2395061da546Spatrick } 2396061da546Spatrick // We currently always true so we stop in case anything goes wrong when 2397061da546Spatrick // trying to call the script function 2398061da546Spatrick return true; 2399061da546Spatrick } 2400061da546Spatrick 2401061da546Spatrick size_t ScriptInterpreterPythonImpl::CalculateNumChildren( 2402061da546Spatrick const StructuredData::ObjectSP &implementor_sp, uint32_t max) { 2403061da546Spatrick if (!implementor_sp) 2404061da546Spatrick return 0; 2405061da546Spatrick StructuredData::Generic *generic = implementor_sp->GetAsGeneric(); 2406061da546Spatrick if (!generic) 2407061da546Spatrick return 0; 2408061da546Spatrick void *implementor = generic->GetValue(); 2409061da546Spatrick if (!implementor) 2410061da546Spatrick return 0; 2411061da546Spatrick 2412061da546Spatrick size_t ret_val = 0; 2413061da546Spatrick 2414061da546Spatrick { 2415061da546Spatrick Locker py_lock(this, 2416061da546Spatrick Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); 2417061da546Spatrick ret_val = LLDBSwigPython_CalculateNumChildren(implementor, max); 2418061da546Spatrick } 2419061da546Spatrick 2420061da546Spatrick return ret_val; 2421061da546Spatrick } 2422061da546Spatrick 2423061da546Spatrick lldb::ValueObjectSP ScriptInterpreterPythonImpl::GetChildAtIndex( 2424061da546Spatrick const StructuredData::ObjectSP &implementor_sp, uint32_t idx) { 2425061da546Spatrick if (!implementor_sp) 2426061da546Spatrick return lldb::ValueObjectSP(); 2427061da546Spatrick 2428061da546Spatrick StructuredData::Generic *generic = implementor_sp->GetAsGeneric(); 2429061da546Spatrick if (!generic) 2430061da546Spatrick return lldb::ValueObjectSP(); 2431061da546Spatrick void *implementor = generic->GetValue(); 2432061da546Spatrick if (!implementor) 2433061da546Spatrick return lldb::ValueObjectSP(); 2434061da546Spatrick 2435061da546Spatrick lldb::ValueObjectSP ret_val; 2436061da546Spatrick { 2437061da546Spatrick Locker py_lock(this, 2438061da546Spatrick Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); 2439061da546Spatrick void *child_ptr = LLDBSwigPython_GetChildAtIndex(implementor, idx); 2440061da546Spatrick if (child_ptr != nullptr && child_ptr != Py_None) { 2441061da546Spatrick lldb::SBValue *sb_value_ptr = 2442061da546Spatrick (lldb::SBValue *)LLDBSWIGPython_CastPyObjectToSBValue(child_ptr); 2443061da546Spatrick if (sb_value_ptr == nullptr) 2444061da546Spatrick Py_XDECREF(child_ptr); 2445061da546Spatrick else 2446061da546Spatrick ret_val = LLDBSWIGPython_GetValueObjectSPFromSBValue(sb_value_ptr); 2447061da546Spatrick } else { 2448061da546Spatrick Py_XDECREF(child_ptr); 2449061da546Spatrick } 2450061da546Spatrick } 2451061da546Spatrick 2452061da546Spatrick return ret_val; 2453061da546Spatrick } 2454061da546Spatrick 2455061da546Spatrick int ScriptInterpreterPythonImpl::GetIndexOfChildWithName( 2456061da546Spatrick const StructuredData::ObjectSP &implementor_sp, const char *child_name) { 2457061da546Spatrick if (!implementor_sp) 2458061da546Spatrick return UINT32_MAX; 2459061da546Spatrick 2460061da546Spatrick StructuredData::Generic *generic = implementor_sp->GetAsGeneric(); 2461061da546Spatrick if (!generic) 2462061da546Spatrick return UINT32_MAX; 2463061da546Spatrick void *implementor = generic->GetValue(); 2464061da546Spatrick if (!implementor) 2465061da546Spatrick return UINT32_MAX; 2466061da546Spatrick 2467061da546Spatrick int ret_val = UINT32_MAX; 2468061da546Spatrick 2469061da546Spatrick { 2470061da546Spatrick Locker py_lock(this, 2471061da546Spatrick Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); 2472061da546Spatrick ret_val = LLDBSwigPython_GetIndexOfChildWithName(implementor, child_name); 2473061da546Spatrick } 2474061da546Spatrick 2475061da546Spatrick return ret_val; 2476061da546Spatrick } 2477061da546Spatrick 2478061da546Spatrick bool ScriptInterpreterPythonImpl::UpdateSynthProviderInstance( 2479061da546Spatrick const StructuredData::ObjectSP &implementor_sp) { 2480061da546Spatrick bool ret_val = false; 2481061da546Spatrick 2482061da546Spatrick if (!implementor_sp) 2483061da546Spatrick return ret_val; 2484061da546Spatrick 2485061da546Spatrick StructuredData::Generic *generic = implementor_sp->GetAsGeneric(); 2486061da546Spatrick if (!generic) 2487061da546Spatrick return ret_val; 2488061da546Spatrick void *implementor = generic->GetValue(); 2489061da546Spatrick if (!implementor) 2490061da546Spatrick return ret_val; 2491061da546Spatrick 2492061da546Spatrick { 2493061da546Spatrick Locker py_lock(this, 2494061da546Spatrick Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); 2495061da546Spatrick ret_val = LLDBSwigPython_UpdateSynthProviderInstance(implementor); 2496061da546Spatrick } 2497061da546Spatrick 2498061da546Spatrick return ret_val; 2499061da546Spatrick } 2500061da546Spatrick 2501061da546Spatrick bool ScriptInterpreterPythonImpl::MightHaveChildrenSynthProviderInstance( 2502061da546Spatrick const StructuredData::ObjectSP &implementor_sp) { 2503061da546Spatrick bool ret_val = false; 2504061da546Spatrick 2505061da546Spatrick if (!implementor_sp) 2506061da546Spatrick return ret_val; 2507061da546Spatrick 2508061da546Spatrick StructuredData::Generic *generic = implementor_sp->GetAsGeneric(); 2509061da546Spatrick if (!generic) 2510061da546Spatrick return ret_val; 2511061da546Spatrick void *implementor = generic->GetValue(); 2512061da546Spatrick if (!implementor) 2513061da546Spatrick return ret_val; 2514061da546Spatrick 2515061da546Spatrick { 2516061da546Spatrick Locker py_lock(this, 2517061da546Spatrick Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); 2518061da546Spatrick ret_val = 2519061da546Spatrick LLDBSwigPython_MightHaveChildrenSynthProviderInstance(implementor); 2520061da546Spatrick } 2521061da546Spatrick 2522061da546Spatrick return ret_val; 2523061da546Spatrick } 2524061da546Spatrick 2525061da546Spatrick lldb::ValueObjectSP ScriptInterpreterPythonImpl::GetSyntheticValue( 2526061da546Spatrick const StructuredData::ObjectSP &implementor_sp) { 2527061da546Spatrick lldb::ValueObjectSP ret_val(nullptr); 2528061da546Spatrick 2529061da546Spatrick if (!implementor_sp) 2530061da546Spatrick return ret_val; 2531061da546Spatrick 2532061da546Spatrick StructuredData::Generic *generic = implementor_sp->GetAsGeneric(); 2533061da546Spatrick if (!generic) 2534061da546Spatrick return ret_val; 2535061da546Spatrick void *implementor = generic->GetValue(); 2536061da546Spatrick if (!implementor) 2537061da546Spatrick return ret_val; 2538061da546Spatrick 2539061da546Spatrick { 2540061da546Spatrick Locker py_lock(this, 2541061da546Spatrick Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); 2542061da546Spatrick void *child_ptr = LLDBSwigPython_GetValueSynthProviderInstance(implementor); 2543061da546Spatrick if (child_ptr != nullptr && child_ptr != Py_None) { 2544061da546Spatrick lldb::SBValue *sb_value_ptr = 2545061da546Spatrick (lldb::SBValue *)LLDBSWIGPython_CastPyObjectToSBValue(child_ptr); 2546061da546Spatrick if (sb_value_ptr == nullptr) 2547061da546Spatrick Py_XDECREF(child_ptr); 2548061da546Spatrick else 2549061da546Spatrick ret_val = LLDBSWIGPython_GetValueObjectSPFromSBValue(sb_value_ptr); 2550061da546Spatrick } else { 2551061da546Spatrick Py_XDECREF(child_ptr); 2552061da546Spatrick } 2553061da546Spatrick } 2554061da546Spatrick 2555061da546Spatrick return ret_val; 2556061da546Spatrick } 2557061da546Spatrick 2558061da546Spatrick ConstString ScriptInterpreterPythonImpl::GetSyntheticTypeName( 2559061da546Spatrick const StructuredData::ObjectSP &implementor_sp) { 2560061da546Spatrick Locker py_lock(this, 2561061da546Spatrick Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); 2562061da546Spatrick 2563061da546Spatrick static char callee_name[] = "get_type_name"; 2564061da546Spatrick 2565061da546Spatrick ConstString ret_val; 2566061da546Spatrick bool got_string = false; 2567061da546Spatrick std::string buffer; 2568061da546Spatrick 2569061da546Spatrick if (!implementor_sp) 2570061da546Spatrick return ret_val; 2571061da546Spatrick 2572061da546Spatrick StructuredData::Generic *generic = implementor_sp->GetAsGeneric(); 2573061da546Spatrick if (!generic) 2574061da546Spatrick return ret_val; 2575061da546Spatrick PythonObject implementor(PyRefType::Borrowed, 2576061da546Spatrick (PyObject *)generic->GetValue()); 2577061da546Spatrick if (!implementor.IsAllocated()) 2578061da546Spatrick return ret_val; 2579061da546Spatrick 2580061da546Spatrick PythonObject pmeth(PyRefType::Owned, 2581061da546Spatrick PyObject_GetAttrString(implementor.get(), callee_name)); 2582061da546Spatrick 2583061da546Spatrick if (PyErr_Occurred()) 2584061da546Spatrick PyErr_Clear(); 2585061da546Spatrick 2586061da546Spatrick if (!pmeth.IsAllocated()) 2587061da546Spatrick return ret_val; 2588061da546Spatrick 2589061da546Spatrick if (PyCallable_Check(pmeth.get()) == 0) { 2590061da546Spatrick if (PyErr_Occurred()) 2591061da546Spatrick PyErr_Clear(); 2592061da546Spatrick return ret_val; 2593061da546Spatrick } 2594061da546Spatrick 2595061da546Spatrick if (PyErr_Occurred()) 2596061da546Spatrick PyErr_Clear(); 2597061da546Spatrick 2598061da546Spatrick // right now we know this function exists and is callable.. 2599061da546Spatrick PythonObject py_return( 2600061da546Spatrick PyRefType::Owned, 2601061da546Spatrick PyObject_CallMethod(implementor.get(), callee_name, nullptr)); 2602061da546Spatrick 2603061da546Spatrick // if it fails, print the error but otherwise go on 2604061da546Spatrick if (PyErr_Occurred()) { 2605061da546Spatrick PyErr_Print(); 2606061da546Spatrick PyErr_Clear(); 2607061da546Spatrick } 2608061da546Spatrick 2609061da546Spatrick if (py_return.IsAllocated() && PythonString::Check(py_return.get())) { 2610061da546Spatrick PythonString py_string(PyRefType::Borrowed, py_return.get()); 2611061da546Spatrick llvm::StringRef return_data(py_string.GetString()); 2612061da546Spatrick if (!return_data.empty()) { 2613061da546Spatrick buffer.assign(return_data.data(), return_data.size()); 2614061da546Spatrick got_string = true; 2615061da546Spatrick } 2616061da546Spatrick } 2617061da546Spatrick 2618061da546Spatrick if (got_string) 2619061da546Spatrick ret_val.SetCStringWithLength(buffer.c_str(), buffer.size()); 2620061da546Spatrick 2621061da546Spatrick return ret_val; 2622061da546Spatrick } 2623061da546Spatrick 2624061da546Spatrick bool ScriptInterpreterPythonImpl::RunScriptFormatKeyword( 2625061da546Spatrick const char *impl_function, Process *process, std::string &output, 2626061da546Spatrick Status &error) { 2627061da546Spatrick bool ret_val; 2628061da546Spatrick if (!process) { 2629061da546Spatrick error.SetErrorString("no process"); 2630061da546Spatrick return false; 2631061da546Spatrick } 2632061da546Spatrick if (!impl_function || !impl_function[0]) { 2633061da546Spatrick error.SetErrorString("no function to execute"); 2634061da546Spatrick return false; 2635061da546Spatrick } 2636061da546Spatrick 2637061da546Spatrick { 2638061da546Spatrick ProcessSP process_sp(process->shared_from_this()); 2639061da546Spatrick Locker py_lock(this, 2640061da546Spatrick Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); 2641061da546Spatrick ret_val = LLDBSWIGPythonRunScriptKeywordProcess( 2642061da546Spatrick impl_function, m_dictionary_name.c_str(), process_sp, output); 2643061da546Spatrick if (!ret_val) 2644061da546Spatrick error.SetErrorString("python script evaluation failed"); 2645061da546Spatrick } 2646061da546Spatrick return ret_val; 2647061da546Spatrick } 2648061da546Spatrick 2649061da546Spatrick bool ScriptInterpreterPythonImpl::RunScriptFormatKeyword( 2650061da546Spatrick const char *impl_function, Thread *thread, std::string &output, 2651061da546Spatrick Status &error) { 2652061da546Spatrick bool ret_val; 2653061da546Spatrick if (!thread) { 2654061da546Spatrick error.SetErrorString("no thread"); 2655061da546Spatrick return false; 2656061da546Spatrick } 2657061da546Spatrick if (!impl_function || !impl_function[0]) { 2658061da546Spatrick error.SetErrorString("no function to execute"); 2659061da546Spatrick return false; 2660061da546Spatrick } 2661061da546Spatrick 2662061da546Spatrick { 2663061da546Spatrick ThreadSP thread_sp(thread->shared_from_this()); 2664061da546Spatrick Locker py_lock(this, 2665061da546Spatrick Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); 2666061da546Spatrick ret_val = LLDBSWIGPythonRunScriptKeywordThread( 2667061da546Spatrick impl_function, m_dictionary_name.c_str(), thread_sp, output); 2668061da546Spatrick if (!ret_val) 2669061da546Spatrick error.SetErrorString("python script evaluation failed"); 2670061da546Spatrick } 2671061da546Spatrick return ret_val; 2672061da546Spatrick } 2673061da546Spatrick 2674061da546Spatrick bool ScriptInterpreterPythonImpl::RunScriptFormatKeyword( 2675061da546Spatrick const char *impl_function, Target *target, std::string &output, 2676061da546Spatrick Status &error) { 2677061da546Spatrick bool ret_val; 2678061da546Spatrick if (!target) { 2679061da546Spatrick error.SetErrorString("no thread"); 2680061da546Spatrick return false; 2681061da546Spatrick } 2682061da546Spatrick if (!impl_function || !impl_function[0]) { 2683061da546Spatrick error.SetErrorString("no function to execute"); 2684061da546Spatrick return false; 2685061da546Spatrick } 2686061da546Spatrick 2687061da546Spatrick { 2688061da546Spatrick TargetSP target_sp(target->shared_from_this()); 2689061da546Spatrick Locker py_lock(this, 2690061da546Spatrick Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); 2691061da546Spatrick ret_val = LLDBSWIGPythonRunScriptKeywordTarget( 2692061da546Spatrick impl_function, m_dictionary_name.c_str(), target_sp, output); 2693061da546Spatrick if (!ret_val) 2694061da546Spatrick error.SetErrorString("python script evaluation failed"); 2695061da546Spatrick } 2696061da546Spatrick return ret_val; 2697061da546Spatrick } 2698061da546Spatrick 2699061da546Spatrick bool ScriptInterpreterPythonImpl::RunScriptFormatKeyword( 2700061da546Spatrick const char *impl_function, StackFrame *frame, std::string &output, 2701061da546Spatrick Status &error) { 2702061da546Spatrick bool ret_val; 2703061da546Spatrick if (!frame) { 2704061da546Spatrick error.SetErrorString("no frame"); 2705061da546Spatrick return false; 2706061da546Spatrick } 2707061da546Spatrick if (!impl_function || !impl_function[0]) { 2708061da546Spatrick error.SetErrorString("no function to execute"); 2709061da546Spatrick return false; 2710061da546Spatrick } 2711061da546Spatrick 2712061da546Spatrick { 2713061da546Spatrick StackFrameSP frame_sp(frame->shared_from_this()); 2714061da546Spatrick Locker py_lock(this, 2715061da546Spatrick Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); 2716061da546Spatrick ret_val = LLDBSWIGPythonRunScriptKeywordFrame( 2717061da546Spatrick impl_function, m_dictionary_name.c_str(), frame_sp, output); 2718061da546Spatrick if (!ret_val) 2719061da546Spatrick error.SetErrorString("python script evaluation failed"); 2720061da546Spatrick } 2721061da546Spatrick return ret_val; 2722061da546Spatrick } 2723061da546Spatrick 2724061da546Spatrick bool ScriptInterpreterPythonImpl::RunScriptFormatKeyword( 2725061da546Spatrick const char *impl_function, ValueObject *value, std::string &output, 2726061da546Spatrick Status &error) { 2727061da546Spatrick bool ret_val; 2728061da546Spatrick if (!value) { 2729061da546Spatrick error.SetErrorString("no value"); 2730061da546Spatrick return false; 2731061da546Spatrick } 2732061da546Spatrick if (!impl_function || !impl_function[0]) { 2733061da546Spatrick error.SetErrorString("no function to execute"); 2734061da546Spatrick return false; 2735061da546Spatrick } 2736061da546Spatrick 2737061da546Spatrick { 2738061da546Spatrick ValueObjectSP value_sp(value->GetSP()); 2739061da546Spatrick Locker py_lock(this, 2740061da546Spatrick Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); 2741061da546Spatrick ret_val = LLDBSWIGPythonRunScriptKeywordValue( 2742061da546Spatrick impl_function, m_dictionary_name.c_str(), value_sp, output); 2743061da546Spatrick if (!ret_val) 2744061da546Spatrick error.SetErrorString("python script evaluation failed"); 2745061da546Spatrick } 2746061da546Spatrick return ret_val; 2747061da546Spatrick } 2748061da546Spatrick 2749061da546Spatrick uint64_t replace_all(std::string &str, const std::string &oldStr, 2750061da546Spatrick const std::string &newStr) { 2751061da546Spatrick size_t pos = 0; 2752061da546Spatrick uint64_t matches = 0; 2753061da546Spatrick while ((pos = str.find(oldStr, pos)) != std::string::npos) { 2754061da546Spatrick matches++; 2755061da546Spatrick str.replace(pos, oldStr.length(), newStr); 2756061da546Spatrick pos += newStr.length(); 2757061da546Spatrick } 2758061da546Spatrick return matches; 2759061da546Spatrick } 2760061da546Spatrick 2761061da546Spatrick bool ScriptInterpreterPythonImpl::LoadScriptingModule( 2762*be691f3bSpatrick const char *pathname, const LoadScriptOptions &options, 2763*be691f3bSpatrick lldb_private::Status &error, StructuredData::ObjectSP *module_sp, 2764*be691f3bSpatrick FileSpec extra_search_dir) { 2765*be691f3bSpatrick namespace fs = llvm::sys::fs; 2766*be691f3bSpatrick namespace path = llvm::sys::path; 2767*be691f3bSpatrick 2768*be691f3bSpatrick ExecuteScriptOptions exc_options = ExecuteScriptOptions() 2769*be691f3bSpatrick .SetEnableIO(!options.GetSilent()) 2770*be691f3bSpatrick .SetSetLLDBGlobals(false); 2771*be691f3bSpatrick 2772061da546Spatrick if (!pathname || !pathname[0]) { 2773061da546Spatrick error.SetErrorString("invalid pathname"); 2774061da546Spatrick return false; 2775061da546Spatrick } 2776061da546Spatrick 2777*be691f3bSpatrick llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>> 2778*be691f3bSpatrick io_redirect_or_error = ScriptInterpreterIORedirect::Create( 2779*be691f3bSpatrick exc_options.GetEnableIO(), m_debugger, /*result=*/nullptr); 2780*be691f3bSpatrick 2781*be691f3bSpatrick if (!io_redirect_or_error) { 2782*be691f3bSpatrick error = io_redirect_or_error.takeError(); 2783*be691f3bSpatrick return false; 2784*be691f3bSpatrick } 2785*be691f3bSpatrick 2786*be691f3bSpatrick ScriptInterpreterIORedirect &io_redirect = **io_redirect_or_error; 2787061da546Spatrick lldb::DebuggerSP debugger_sp = m_debugger.shared_from_this(); 2788061da546Spatrick 2789061da546Spatrick // Before executing Python code, lock the GIL. 2790061da546Spatrick Locker py_lock(this, 2791061da546Spatrick Locker::AcquireLock | 2792*be691f3bSpatrick (options.GetInitSession() ? Locker::InitSession : 0) | 2793061da546Spatrick Locker::NoSTDIN, 2794061da546Spatrick Locker::FreeAcquiredLock | 2795*be691f3bSpatrick (options.GetInitSession() ? Locker::TearDownSession : 0), 2796*be691f3bSpatrick io_redirect.GetInputFile(), io_redirect.GetOutputFile(), 2797*be691f3bSpatrick io_redirect.GetErrorFile()); 2798*be691f3bSpatrick 2799*be691f3bSpatrick auto ExtendSysPath = [&](std::string directory) -> llvm::Error { 2800*be691f3bSpatrick if (directory.empty()) { 2801*be691f3bSpatrick return llvm::make_error<llvm::StringError>( 2802*be691f3bSpatrick "invalid directory name", llvm::inconvertibleErrorCode()); 2803*be691f3bSpatrick } 2804*be691f3bSpatrick 2805*be691f3bSpatrick replace_all(directory, "\\", "\\\\"); 2806*be691f3bSpatrick replace_all(directory, "'", "\\'"); 2807*be691f3bSpatrick 2808*be691f3bSpatrick // Make sure that Python has "directory" in the search path. 2809*be691f3bSpatrick StreamString command_stream; 2810*be691f3bSpatrick command_stream.Printf("if not (sys.path.__contains__('%s')):\n " 2811*be691f3bSpatrick "sys.path.insert(1,'%s');\n\n", 2812*be691f3bSpatrick directory.c_str(), directory.c_str()); 2813*be691f3bSpatrick bool syspath_retval = 2814*be691f3bSpatrick ExecuteMultipleLines(command_stream.GetData(), exc_options).Success(); 2815*be691f3bSpatrick if (!syspath_retval) { 2816*be691f3bSpatrick return llvm::make_error<llvm::StringError>( 2817*be691f3bSpatrick "Python sys.path handling failed", llvm::inconvertibleErrorCode()); 2818*be691f3bSpatrick } 2819*be691f3bSpatrick 2820*be691f3bSpatrick return llvm::Error::success(); 2821*be691f3bSpatrick }; 2822*be691f3bSpatrick 2823*be691f3bSpatrick std::string module_name(pathname); 2824*be691f3bSpatrick bool possible_package = false; 2825*be691f3bSpatrick 2826*be691f3bSpatrick if (extra_search_dir) { 2827*be691f3bSpatrick if (llvm::Error e = ExtendSysPath(extra_search_dir.GetPath())) { 2828*be691f3bSpatrick error = std::move(e); 2829*be691f3bSpatrick return false; 2830*be691f3bSpatrick } 2831*be691f3bSpatrick } else { 2832*be691f3bSpatrick FileSpec module_file(pathname); 2833*be691f3bSpatrick FileSystem::Instance().Resolve(module_file); 2834*be691f3bSpatrick FileSystem::Instance().Collect(module_file); 2835*be691f3bSpatrick 2836061da546Spatrick fs::file_status st; 2837*be691f3bSpatrick std::error_code ec = status(module_file.GetPath(), st); 2838061da546Spatrick 2839061da546Spatrick if (ec || st.type() == fs::file_type::status_error || 2840061da546Spatrick st.type() == fs::file_type::type_unknown || 2841061da546Spatrick st.type() == fs::file_type::file_not_found) { 2842061da546Spatrick // if not a valid file of any sort, check if it might be a filename still 2843061da546Spatrick // dot can't be used but / and \ can, and if either is found, reject 2844061da546Spatrick if (strchr(pathname, '\\') || strchr(pathname, '/')) { 2845061da546Spatrick error.SetErrorString("invalid pathname"); 2846061da546Spatrick return false; 2847061da546Spatrick } 2848*be691f3bSpatrick // Not a filename, probably a package of some sort, let it go through. 2849*be691f3bSpatrick possible_package = true; 2850061da546Spatrick } else if (is_directory(st) || is_regular_file(st)) { 2851*be691f3bSpatrick if (module_file.GetDirectory().IsEmpty()) { 2852061da546Spatrick error.SetErrorString("invalid directory name"); 2853061da546Spatrick return false; 2854061da546Spatrick } 2855*be691f3bSpatrick if (llvm::Error e = 2856*be691f3bSpatrick ExtendSysPath(module_file.GetDirectory().GetCString())) { 2857*be691f3bSpatrick error = std::move(e); 2858061da546Spatrick return false; 2859061da546Spatrick } 2860*be691f3bSpatrick module_name = module_file.GetFilename().GetCString(); 2861061da546Spatrick } else { 2862061da546Spatrick error.SetErrorString("no known way to import this module specification"); 2863061da546Spatrick return false; 2864061da546Spatrick } 2865*be691f3bSpatrick } 2866061da546Spatrick 2867*be691f3bSpatrick // Strip .py or .pyc extension 2868*be691f3bSpatrick llvm::StringRef extension = llvm::sys::path::extension(module_name); 2869*be691f3bSpatrick if (!extension.empty()) { 2870*be691f3bSpatrick if (extension == ".py") 2871*be691f3bSpatrick module_name.resize(module_name.length() - 3); 2872*be691f3bSpatrick else if (extension == ".pyc") 2873*be691f3bSpatrick module_name.resize(module_name.length() - 4); 2874*be691f3bSpatrick } 2875*be691f3bSpatrick 2876*be691f3bSpatrick if (!possible_package && module_name.find('.') != llvm::StringRef::npos) { 2877*be691f3bSpatrick error.SetErrorStringWithFormat( 2878*be691f3bSpatrick "Python does not allow dots in module names: %s", module_name.c_str()); 2879*be691f3bSpatrick return false; 2880*be691f3bSpatrick } 2881*be691f3bSpatrick 2882*be691f3bSpatrick if (module_name.find('-') != llvm::StringRef::npos) { 2883*be691f3bSpatrick error.SetErrorStringWithFormat( 2884*be691f3bSpatrick "Python discourages dashes in module names: %s", module_name.c_str()); 2885*be691f3bSpatrick return false; 2886*be691f3bSpatrick } 2887*be691f3bSpatrick 2888*be691f3bSpatrick // Check if the module is already imported. 2889*be691f3bSpatrick StreamString command_stream; 2890061da546Spatrick command_stream.Clear(); 2891*be691f3bSpatrick command_stream.Printf("sys.modules.__contains__('%s')", module_name.c_str()); 2892061da546Spatrick bool does_contain = false; 2893*be691f3bSpatrick // This call will succeed if the module was ever imported in any Debugger in 2894*be691f3bSpatrick // the lifetime of the process in which this LLDB framework is living. 2895*be691f3bSpatrick const bool does_contain_executed = ExecuteOneLineWithReturn( 2896061da546Spatrick command_stream.GetData(), 2897*be691f3bSpatrick ScriptInterpreterPythonImpl::eScriptReturnTypeBool, &does_contain, exc_options); 2898061da546Spatrick 2899*be691f3bSpatrick const bool was_imported_globally = does_contain_executed && does_contain; 2900*be691f3bSpatrick const bool was_imported_locally = 2901*be691f3bSpatrick GetSessionDictionary() 2902*be691f3bSpatrick .GetItemForKey(PythonString(module_name)) 2903*be691f3bSpatrick .IsAllocated(); 2904061da546Spatrick 2905061da546Spatrick // now actually do the import 2906061da546Spatrick command_stream.Clear(); 2907061da546Spatrick 2908*be691f3bSpatrick if (was_imported_globally || was_imported_locally) { 2909061da546Spatrick if (!was_imported_locally) 2910*be691f3bSpatrick command_stream.Printf("import %s ; reload_module(%s)", 2911*be691f3bSpatrick module_name.c_str(), module_name.c_str()); 2912061da546Spatrick else 2913*be691f3bSpatrick command_stream.Printf("reload_module(%s)", module_name.c_str()); 2914061da546Spatrick } else 2915*be691f3bSpatrick command_stream.Printf("import %s", module_name.c_str()); 2916061da546Spatrick 2917*be691f3bSpatrick error = ExecuteMultipleLines(command_stream.GetData(), exc_options); 2918061da546Spatrick if (error.Fail()) 2919061da546Spatrick return false; 2920061da546Spatrick 2921061da546Spatrick // if we are here, everything worked 2922061da546Spatrick // call __lldb_init_module(debugger,dict) 2923*be691f3bSpatrick if (!LLDBSwigPythonCallModuleInit(module_name.c_str(), 2924061da546Spatrick m_dictionary_name.c_str(), debugger_sp)) { 2925061da546Spatrick error.SetErrorString("calling __lldb_init_module failed"); 2926061da546Spatrick return false; 2927061da546Spatrick } 2928061da546Spatrick 2929061da546Spatrick if (module_sp) { 2930061da546Spatrick // everything went just great, now set the module object 2931061da546Spatrick command_stream.Clear(); 2932*be691f3bSpatrick command_stream.Printf("%s", module_name.c_str()); 2933061da546Spatrick void *module_pyobj = nullptr; 2934061da546Spatrick if (ExecuteOneLineWithReturn( 2935061da546Spatrick command_stream.GetData(), 2936*be691f3bSpatrick ScriptInterpreter::eScriptReturnTypeOpaqueObject, &module_pyobj, 2937*be691f3bSpatrick exc_options) && 2938061da546Spatrick module_pyobj) 2939061da546Spatrick *module_sp = std::make_shared<StructuredPythonObject>(module_pyobj); 2940061da546Spatrick } 2941061da546Spatrick 2942061da546Spatrick return true; 2943061da546Spatrick } 2944061da546Spatrick 2945061da546Spatrick bool ScriptInterpreterPythonImpl::IsReservedWord(const char *word) { 2946061da546Spatrick if (!word || !word[0]) 2947061da546Spatrick return false; 2948061da546Spatrick 2949061da546Spatrick llvm::StringRef word_sr(word); 2950061da546Spatrick 2951061da546Spatrick // filter out a few characters that would just confuse us and that are 2952061da546Spatrick // clearly not keyword material anyway 2953061da546Spatrick if (word_sr.find('"') != llvm::StringRef::npos || 2954061da546Spatrick word_sr.find('\'') != llvm::StringRef::npos) 2955061da546Spatrick return false; 2956061da546Spatrick 2957061da546Spatrick StreamString command_stream; 2958061da546Spatrick command_stream.Printf("keyword.iskeyword('%s')", word); 2959061da546Spatrick bool result; 2960061da546Spatrick ExecuteScriptOptions options; 2961061da546Spatrick options.SetEnableIO(false); 2962061da546Spatrick options.SetMaskoutErrors(true); 2963061da546Spatrick options.SetSetLLDBGlobals(false); 2964061da546Spatrick if (ExecuteOneLineWithReturn(command_stream.GetData(), 2965061da546Spatrick ScriptInterpreter::eScriptReturnTypeBool, 2966061da546Spatrick &result, options)) 2967061da546Spatrick return result; 2968061da546Spatrick return false; 2969061da546Spatrick } 2970061da546Spatrick 2971061da546Spatrick ScriptInterpreterPythonImpl::SynchronicityHandler::SynchronicityHandler( 2972061da546Spatrick lldb::DebuggerSP debugger_sp, ScriptedCommandSynchronicity synchro) 2973061da546Spatrick : m_debugger_sp(debugger_sp), m_synch_wanted(synchro), 2974061da546Spatrick m_old_asynch(debugger_sp->GetAsyncExecution()) { 2975061da546Spatrick if (m_synch_wanted == eScriptedCommandSynchronicitySynchronous) 2976061da546Spatrick m_debugger_sp->SetAsyncExecution(false); 2977061da546Spatrick else if (m_synch_wanted == eScriptedCommandSynchronicityAsynchronous) 2978061da546Spatrick m_debugger_sp->SetAsyncExecution(true); 2979061da546Spatrick } 2980061da546Spatrick 2981061da546Spatrick ScriptInterpreterPythonImpl::SynchronicityHandler::~SynchronicityHandler() { 2982061da546Spatrick if (m_synch_wanted != eScriptedCommandSynchronicityCurrentValue) 2983061da546Spatrick m_debugger_sp->SetAsyncExecution(m_old_asynch); 2984061da546Spatrick } 2985061da546Spatrick 2986061da546Spatrick bool ScriptInterpreterPythonImpl::RunScriptBasedCommand( 2987061da546Spatrick const char *impl_function, llvm::StringRef args, 2988061da546Spatrick ScriptedCommandSynchronicity synchronicity, 2989061da546Spatrick lldb_private::CommandReturnObject &cmd_retobj, Status &error, 2990061da546Spatrick const lldb_private::ExecutionContext &exe_ctx) { 2991061da546Spatrick if (!impl_function) { 2992061da546Spatrick error.SetErrorString("no function to execute"); 2993061da546Spatrick return false; 2994061da546Spatrick } 2995061da546Spatrick 2996061da546Spatrick lldb::DebuggerSP debugger_sp = m_debugger.shared_from_this(); 2997061da546Spatrick lldb::ExecutionContextRefSP exe_ctx_ref_sp(new ExecutionContextRef(exe_ctx)); 2998061da546Spatrick 2999061da546Spatrick if (!debugger_sp.get()) { 3000061da546Spatrick error.SetErrorString("invalid Debugger pointer"); 3001061da546Spatrick return false; 3002061da546Spatrick } 3003061da546Spatrick 3004061da546Spatrick bool ret_val = false; 3005061da546Spatrick 3006061da546Spatrick std::string err_msg; 3007061da546Spatrick 3008061da546Spatrick { 3009061da546Spatrick Locker py_lock(this, 3010061da546Spatrick Locker::AcquireLock | Locker::InitSession | 3011061da546Spatrick (cmd_retobj.GetInteractive() ? 0 : Locker::NoSTDIN), 3012061da546Spatrick Locker::FreeLock | Locker::TearDownSession); 3013061da546Spatrick 3014061da546Spatrick SynchronicityHandler synch_handler(debugger_sp, synchronicity); 3015061da546Spatrick 3016061da546Spatrick std::string args_str = args.str(); 3017061da546Spatrick ret_val = LLDBSwigPythonCallCommand( 3018061da546Spatrick impl_function, m_dictionary_name.c_str(), debugger_sp, args_str.c_str(), 3019061da546Spatrick cmd_retobj, exe_ctx_ref_sp); 3020061da546Spatrick } 3021061da546Spatrick 3022061da546Spatrick if (!ret_val) 3023061da546Spatrick error.SetErrorString("unable to execute script function"); 3024061da546Spatrick else 3025061da546Spatrick error.Clear(); 3026061da546Spatrick 3027061da546Spatrick return ret_val; 3028061da546Spatrick } 3029061da546Spatrick 3030061da546Spatrick bool ScriptInterpreterPythonImpl::RunScriptBasedCommand( 3031061da546Spatrick StructuredData::GenericSP impl_obj_sp, llvm::StringRef args, 3032061da546Spatrick ScriptedCommandSynchronicity synchronicity, 3033061da546Spatrick lldb_private::CommandReturnObject &cmd_retobj, Status &error, 3034061da546Spatrick const lldb_private::ExecutionContext &exe_ctx) { 3035061da546Spatrick if (!impl_obj_sp || !impl_obj_sp->IsValid()) { 3036061da546Spatrick error.SetErrorString("no function to execute"); 3037061da546Spatrick return false; 3038061da546Spatrick } 3039061da546Spatrick 3040061da546Spatrick lldb::DebuggerSP debugger_sp = m_debugger.shared_from_this(); 3041061da546Spatrick lldb::ExecutionContextRefSP exe_ctx_ref_sp(new ExecutionContextRef(exe_ctx)); 3042061da546Spatrick 3043061da546Spatrick if (!debugger_sp.get()) { 3044061da546Spatrick error.SetErrorString("invalid Debugger pointer"); 3045061da546Spatrick return false; 3046061da546Spatrick } 3047061da546Spatrick 3048061da546Spatrick bool ret_val = false; 3049061da546Spatrick 3050061da546Spatrick std::string err_msg; 3051061da546Spatrick 3052061da546Spatrick { 3053061da546Spatrick Locker py_lock(this, 3054061da546Spatrick Locker::AcquireLock | Locker::InitSession | 3055061da546Spatrick (cmd_retobj.GetInteractive() ? 0 : Locker::NoSTDIN), 3056061da546Spatrick Locker::FreeLock | Locker::TearDownSession); 3057061da546Spatrick 3058061da546Spatrick SynchronicityHandler synch_handler(debugger_sp, synchronicity); 3059061da546Spatrick 3060061da546Spatrick std::string args_str = args.str(); 3061061da546Spatrick ret_val = LLDBSwigPythonCallCommandObject(impl_obj_sp->GetValue(), 3062061da546Spatrick debugger_sp, args_str.c_str(), 3063061da546Spatrick cmd_retobj, exe_ctx_ref_sp); 3064061da546Spatrick } 3065061da546Spatrick 3066061da546Spatrick if (!ret_val) 3067061da546Spatrick error.SetErrorString("unable to execute script function"); 3068061da546Spatrick else 3069061da546Spatrick error.Clear(); 3070061da546Spatrick 3071061da546Spatrick return ret_val; 3072061da546Spatrick } 3073061da546Spatrick 3074dda28197Spatrick /// In Python, a special attribute __doc__ contains the docstring for an object 3075dda28197Spatrick /// (function, method, class, ...) if any is defined Otherwise, the attribute's 3076dda28197Spatrick /// value is None. 3077061da546Spatrick bool ScriptInterpreterPythonImpl::GetDocumentationForItem(const char *item, 3078061da546Spatrick std::string &dest) { 3079061da546Spatrick dest.clear(); 3080dda28197Spatrick 3081061da546Spatrick if (!item || !*item) 3082061da546Spatrick return false; 3083dda28197Spatrick 3084061da546Spatrick std::string command(item); 3085061da546Spatrick command += ".__doc__"; 3086061da546Spatrick 3087dda28197Spatrick // Python is going to point this to valid data if ExecuteOneLineWithReturn 3088dda28197Spatrick // returns successfully. 3089dda28197Spatrick char *result_ptr = nullptr; 3090061da546Spatrick 3091061da546Spatrick if (ExecuteOneLineWithReturn( 3092dda28197Spatrick command, ScriptInterpreter::eScriptReturnTypeCharStrOrNone, 3093061da546Spatrick &result_ptr, 3094*be691f3bSpatrick ExecuteScriptOptions().SetEnableIO(false))) { 3095061da546Spatrick if (result_ptr) 3096061da546Spatrick dest.assign(result_ptr); 3097061da546Spatrick return true; 3098061da546Spatrick } 3099dda28197Spatrick 3100dda28197Spatrick StreamString str_stream; 3101dda28197Spatrick str_stream << "Function " << item 3102dda28197Spatrick << " was not found. Containing module might be missing."; 3103dda28197Spatrick dest = std::string(str_stream.GetString()); 3104dda28197Spatrick 3105dda28197Spatrick return false; 3106061da546Spatrick } 3107061da546Spatrick 3108061da546Spatrick bool ScriptInterpreterPythonImpl::GetShortHelpForCommandObject( 3109061da546Spatrick StructuredData::GenericSP cmd_obj_sp, std::string &dest) { 3110061da546Spatrick dest.clear(); 3111061da546Spatrick 3112061da546Spatrick Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock); 3113061da546Spatrick 3114061da546Spatrick static char callee_name[] = "get_short_help"; 3115061da546Spatrick 3116061da546Spatrick if (!cmd_obj_sp) 3117061da546Spatrick return false; 3118061da546Spatrick 3119061da546Spatrick PythonObject implementor(PyRefType::Borrowed, 3120061da546Spatrick (PyObject *)cmd_obj_sp->GetValue()); 3121061da546Spatrick 3122061da546Spatrick if (!implementor.IsAllocated()) 3123061da546Spatrick return false; 3124061da546Spatrick 3125061da546Spatrick PythonObject pmeth(PyRefType::Owned, 3126061da546Spatrick PyObject_GetAttrString(implementor.get(), callee_name)); 3127061da546Spatrick 3128061da546Spatrick if (PyErr_Occurred()) 3129061da546Spatrick PyErr_Clear(); 3130061da546Spatrick 3131061da546Spatrick if (!pmeth.IsAllocated()) 3132061da546Spatrick return false; 3133061da546Spatrick 3134061da546Spatrick if (PyCallable_Check(pmeth.get()) == 0) { 3135061da546Spatrick if (PyErr_Occurred()) 3136061da546Spatrick PyErr_Clear(); 3137061da546Spatrick return false; 3138061da546Spatrick } 3139061da546Spatrick 3140061da546Spatrick if (PyErr_Occurred()) 3141061da546Spatrick PyErr_Clear(); 3142061da546Spatrick 3143dda28197Spatrick // Right now we know this function exists and is callable. 3144061da546Spatrick PythonObject py_return( 3145061da546Spatrick PyRefType::Owned, 3146061da546Spatrick PyObject_CallMethod(implementor.get(), callee_name, nullptr)); 3147061da546Spatrick 3148dda28197Spatrick // If it fails, print the error but otherwise go on. 3149061da546Spatrick if (PyErr_Occurred()) { 3150061da546Spatrick PyErr_Print(); 3151061da546Spatrick PyErr_Clear(); 3152061da546Spatrick } 3153061da546Spatrick 3154061da546Spatrick if (py_return.IsAllocated() && PythonString::Check(py_return.get())) { 3155061da546Spatrick PythonString py_string(PyRefType::Borrowed, py_return.get()); 3156061da546Spatrick llvm::StringRef return_data(py_string.GetString()); 3157061da546Spatrick dest.assign(return_data.data(), return_data.size()); 3158dda28197Spatrick return true; 3159061da546Spatrick } 3160dda28197Spatrick 3161dda28197Spatrick return false; 3162061da546Spatrick } 3163061da546Spatrick 3164061da546Spatrick uint32_t ScriptInterpreterPythonImpl::GetFlagsForCommandObject( 3165061da546Spatrick StructuredData::GenericSP cmd_obj_sp) { 3166061da546Spatrick uint32_t result = 0; 3167061da546Spatrick 3168061da546Spatrick Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock); 3169061da546Spatrick 3170061da546Spatrick static char callee_name[] = "get_flags"; 3171061da546Spatrick 3172061da546Spatrick if (!cmd_obj_sp) 3173061da546Spatrick return result; 3174061da546Spatrick 3175061da546Spatrick PythonObject implementor(PyRefType::Borrowed, 3176061da546Spatrick (PyObject *)cmd_obj_sp->GetValue()); 3177061da546Spatrick 3178061da546Spatrick if (!implementor.IsAllocated()) 3179061da546Spatrick return result; 3180061da546Spatrick 3181061da546Spatrick PythonObject pmeth(PyRefType::Owned, 3182061da546Spatrick PyObject_GetAttrString(implementor.get(), callee_name)); 3183061da546Spatrick 3184061da546Spatrick if (PyErr_Occurred()) 3185061da546Spatrick PyErr_Clear(); 3186061da546Spatrick 3187061da546Spatrick if (!pmeth.IsAllocated()) 3188061da546Spatrick return result; 3189061da546Spatrick 3190061da546Spatrick if (PyCallable_Check(pmeth.get()) == 0) { 3191061da546Spatrick if (PyErr_Occurred()) 3192061da546Spatrick PyErr_Clear(); 3193061da546Spatrick return result; 3194061da546Spatrick } 3195061da546Spatrick 3196061da546Spatrick if (PyErr_Occurred()) 3197061da546Spatrick PyErr_Clear(); 3198061da546Spatrick 3199dda28197Spatrick long long py_return = unwrapOrSetPythonException( 3200dda28197Spatrick As<long long>(implementor.CallMethod(callee_name))); 3201061da546Spatrick 3202061da546Spatrick // if it fails, print the error but otherwise go on 3203061da546Spatrick if (PyErr_Occurred()) { 3204061da546Spatrick PyErr_Print(); 3205061da546Spatrick PyErr_Clear(); 3206dda28197Spatrick } else { 3207dda28197Spatrick result = py_return; 3208061da546Spatrick } 3209061da546Spatrick 3210061da546Spatrick return result; 3211061da546Spatrick } 3212061da546Spatrick 3213061da546Spatrick bool ScriptInterpreterPythonImpl::GetLongHelpForCommandObject( 3214061da546Spatrick StructuredData::GenericSP cmd_obj_sp, std::string &dest) { 3215061da546Spatrick bool got_string = false; 3216061da546Spatrick dest.clear(); 3217061da546Spatrick 3218061da546Spatrick Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock); 3219061da546Spatrick 3220061da546Spatrick static char callee_name[] = "get_long_help"; 3221061da546Spatrick 3222061da546Spatrick if (!cmd_obj_sp) 3223061da546Spatrick return false; 3224061da546Spatrick 3225061da546Spatrick PythonObject implementor(PyRefType::Borrowed, 3226061da546Spatrick (PyObject *)cmd_obj_sp->GetValue()); 3227061da546Spatrick 3228061da546Spatrick if (!implementor.IsAllocated()) 3229061da546Spatrick return false; 3230061da546Spatrick 3231061da546Spatrick PythonObject pmeth(PyRefType::Owned, 3232061da546Spatrick PyObject_GetAttrString(implementor.get(), callee_name)); 3233061da546Spatrick 3234061da546Spatrick if (PyErr_Occurred()) 3235061da546Spatrick PyErr_Clear(); 3236061da546Spatrick 3237061da546Spatrick if (!pmeth.IsAllocated()) 3238061da546Spatrick return false; 3239061da546Spatrick 3240061da546Spatrick if (PyCallable_Check(pmeth.get()) == 0) { 3241061da546Spatrick if (PyErr_Occurred()) 3242061da546Spatrick PyErr_Clear(); 3243061da546Spatrick 3244061da546Spatrick return false; 3245061da546Spatrick } 3246061da546Spatrick 3247061da546Spatrick if (PyErr_Occurred()) 3248061da546Spatrick PyErr_Clear(); 3249061da546Spatrick 3250061da546Spatrick // right now we know this function exists and is callable.. 3251061da546Spatrick PythonObject py_return( 3252061da546Spatrick PyRefType::Owned, 3253061da546Spatrick PyObject_CallMethod(implementor.get(), callee_name, nullptr)); 3254061da546Spatrick 3255061da546Spatrick // if it fails, print the error but otherwise go on 3256061da546Spatrick if (PyErr_Occurred()) { 3257061da546Spatrick PyErr_Print(); 3258061da546Spatrick PyErr_Clear(); 3259061da546Spatrick } 3260061da546Spatrick 3261061da546Spatrick if (py_return.IsAllocated() && PythonString::Check(py_return.get())) { 3262061da546Spatrick PythonString str(PyRefType::Borrowed, py_return.get()); 3263061da546Spatrick llvm::StringRef str_data(str.GetString()); 3264061da546Spatrick dest.assign(str_data.data(), str_data.size()); 3265061da546Spatrick got_string = true; 3266061da546Spatrick } 3267061da546Spatrick 3268061da546Spatrick return got_string; 3269061da546Spatrick } 3270061da546Spatrick 3271061da546Spatrick std::unique_ptr<ScriptInterpreterLocker> 3272061da546Spatrick ScriptInterpreterPythonImpl::AcquireInterpreterLock() { 3273061da546Spatrick std::unique_ptr<ScriptInterpreterLocker> py_lock(new Locker( 3274061da546Spatrick this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN, 3275061da546Spatrick Locker::FreeLock | Locker::TearDownSession)); 3276061da546Spatrick return py_lock; 3277061da546Spatrick } 3278061da546Spatrick 3279061da546Spatrick void ScriptInterpreterPythonImpl::InitializePrivate() { 3280061da546Spatrick if (g_initialized) 3281061da546Spatrick return; 3282061da546Spatrick 3283061da546Spatrick g_initialized = true; 3284061da546Spatrick 3285*be691f3bSpatrick LLDB_SCOPED_TIMER(); 3286061da546Spatrick 3287061da546Spatrick // RAII-based initialization which correctly handles multiple-initialization, 3288061da546Spatrick // version- specific differences among Python 2 and Python 3, and saving and 3289061da546Spatrick // restoring various other pieces of state that can get mucked with during 3290061da546Spatrick // initialization. 3291061da546Spatrick InitializePythonRAII initialize_guard; 3292061da546Spatrick 3293061da546Spatrick LLDBSwigPyInit(); 3294061da546Spatrick 3295061da546Spatrick // Update the path python uses to search for modules to include the current 3296061da546Spatrick // directory. 3297061da546Spatrick 3298061da546Spatrick PyRun_SimpleString("import sys"); 3299061da546Spatrick AddToSysPath(AddLocation::End, "."); 3300061da546Spatrick 3301061da546Spatrick // Don't denormalize paths when calling file_spec.GetPath(). On platforms 3302061da546Spatrick // that use a backslash as the path separator, this will result in executing 3303061da546Spatrick // python code containing paths with unescaped backslashes. But Python also 3304061da546Spatrick // accepts forward slashes, so to make life easier we just use that. 3305061da546Spatrick if (FileSpec file_spec = GetPythonDir()) 3306061da546Spatrick AddToSysPath(AddLocation::Beginning, file_spec.GetPath(false)); 3307061da546Spatrick if (FileSpec file_spec = HostInfo::GetShlibDir()) 3308061da546Spatrick AddToSysPath(AddLocation::Beginning, file_spec.GetPath(false)); 3309061da546Spatrick 3310061da546Spatrick PyRun_SimpleString("sys.dont_write_bytecode = 1; import " 3311061da546Spatrick "lldb.embedded_interpreter; from " 3312061da546Spatrick "lldb.embedded_interpreter import run_python_interpreter; " 3313061da546Spatrick "from lldb.embedded_interpreter import run_one_line"); 3314061da546Spatrick } 3315061da546Spatrick 3316061da546Spatrick void ScriptInterpreterPythonImpl::AddToSysPath(AddLocation location, 3317061da546Spatrick std::string path) { 3318061da546Spatrick std::string path_copy; 3319061da546Spatrick 3320061da546Spatrick std::string statement; 3321061da546Spatrick if (location == AddLocation::Beginning) { 3322061da546Spatrick statement.assign("sys.path.insert(0,\""); 3323061da546Spatrick statement.append(path); 3324061da546Spatrick statement.append("\")"); 3325061da546Spatrick } else { 3326061da546Spatrick statement.assign("sys.path.append(\""); 3327061da546Spatrick statement.append(path); 3328061da546Spatrick statement.append("\")"); 3329061da546Spatrick } 3330061da546Spatrick PyRun_SimpleString(statement.c_str()); 3331061da546Spatrick } 3332061da546Spatrick 3333061da546Spatrick // We are intentionally NOT calling Py_Finalize here (this would be the logical 3334061da546Spatrick // place to call it). Calling Py_Finalize here causes test suite runs to seg 3335061da546Spatrick // fault: The test suite runs in Python. It registers SBDebugger::Terminate to 3336061da546Spatrick // be called 'at_exit'. When the test suite Python harness finishes up, it 3337061da546Spatrick // calls Py_Finalize, which calls all the 'at_exit' registered functions. 3338061da546Spatrick // SBDebugger::Terminate calls Debugger::Terminate, which calls lldb::Terminate, 3339061da546Spatrick // which calls ScriptInterpreter::Terminate, which calls 3340061da546Spatrick // ScriptInterpreterPythonImpl::Terminate. So if we call Py_Finalize here, we 3341061da546Spatrick // end up with Py_Finalize being called from within Py_Finalize, which results 3342061da546Spatrick // in a seg fault. Since this function only gets called when lldb is shutting 3343061da546Spatrick // down and going away anyway, the fact that we don't actually call Py_Finalize 3344061da546Spatrick // should not cause any problems (everything should shut down/go away anyway 3345061da546Spatrick // when the process exits). 3346061da546Spatrick // 3347061da546Spatrick // void ScriptInterpreterPythonImpl::Terminate() { Py_Finalize (); } 3348061da546Spatrick 3349061da546Spatrick #endif 3350