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