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