diff options
Diffstat (limited to 'lldb/source/Interpreter/ScriptInterpreterPython.cpp')
-rw-r--r-- | lldb/source/Interpreter/ScriptInterpreterPython.cpp | 271 |
1 files changed, 182 insertions, 89 deletions
diff --git a/lldb/source/Interpreter/ScriptInterpreterPython.cpp b/lldb/source/Interpreter/ScriptInterpreterPython.cpp index d3b9cf90106..3dce1c5d478 100644 --- a/lldb/source/Interpreter/ScriptInterpreterPython.cpp +++ b/lldb/source/Interpreter/ScriptInterpreterPython.cpp @@ -135,7 +135,7 @@ ScriptInterpreterPython::Locker::Locker (ScriptInterpreterPython *py_interpreter uint16_t on_entry, uint16_t on_leave, FILE* wait_msg_handle) : - m_need_session( (on_leave & TearDownSession) == TearDownSession ), + m_teardown_session( (on_leave & TearDownSession) == TearDownSession ), m_python_interpreter(py_interpreter), m_tmp_fh(wait_msg_handle) { @@ -144,7 +144,13 @@ ScriptInterpreterPython::Locker::Locker (ScriptInterpreterPython *py_interpreter DoAcquireLock(); if ((on_entry & InitSession) == InitSession) - DoInitSession((on_entry & InitGlobals) == InitGlobals); + { + if (DoInitSession((on_entry & InitGlobals) == InitGlobals) == false) + { + // Don't teardown the session if we didn't init it. + m_teardown_session = false; + } + } } bool @@ -162,8 +168,7 @@ ScriptInterpreterPython::Locker::DoInitSession(bool init_lldb_globals) { if (!m_python_interpreter) return false; - m_python_interpreter->EnterSession (init_lldb_globals); - return true; + return m_python_interpreter->EnterSession (init_lldb_globals); } bool @@ -187,7 +192,7 @@ ScriptInterpreterPython::Locker::DoTearDownSession() ScriptInterpreterPython::Locker::~Locker() { - if (m_need_session) + if (m_teardown_session) DoTearDownSession(); DoFreeLock(); } @@ -254,14 +259,11 @@ ScriptInterpreterPython::PythonInputReaderManager::~PythonInputReaderManager() } size_t -ScriptInterpreterPython::PythonInputReaderManager::InputReaderCallback -( - void *baton, - InputReader &reader, - InputReaderAction notification, - const char *bytes, - size_t bytes_len - ) +ScriptInterpreterPython::PythonInputReaderManager::InputReaderCallback (void *baton, + InputReader &reader, + InputReaderAction notification, + const char *bytes, + size_t bytes_len) { lldb::thread_t embedded_interpreter_thread; LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SCRIPT)); @@ -364,22 +366,22 @@ ScriptInterpreterPython::PythonInputReaderManager::InputReaderCallback break; case eInputReaderInterrupt: - { - PyThreadState* state = _PyThreadState_Current; - if (!state) - state = script_interpreter->m_command_thread_state; - if (state) { - long tid = state->thread_id; - _PyThreadState_Current = state; - int num_threads = PyThreadState_SetAsyncExc(tid, PyExc_KeyboardInterrupt); - if (log) - log->Printf("ScriptInterpreterPython::NonInteractiveInputReaderCallback, eInputReaderInterrupt, tid = %ld, num_threads = %d, state = %p", - tid,num_threads,state); + PyThreadState* state = _PyThreadState_Current; + if (!state) + state = script_interpreter->m_command_thread_state; + if (state) + { + long tid = state->thread_id; + _PyThreadState_Current = state; + int num_threads = PyThreadState_SetAsyncExc(tid, PyExc_KeyboardInterrupt); + if (log) + log->Printf("ScriptInterpreterPython::NonInteractiveInputReaderCallback, eInputReaderInterrupt, tid = %ld, num_threads = %d, state = %p", + tid,num_threads,state); + } + else if (log) + log->Printf("ScriptInterpreterPython::NonInteractiveInputReaderCallback, eInputReaderInterrupt, state = NULL"); } - else if (log) - log->Printf("ScriptInterpreterPython::NonInteractiveInputReaderCallback, eInputReaderInterrupt, state = NULL"); - } break; case eInputReaderEndOfFile: @@ -404,36 +406,30 @@ ScriptInterpreterPython::PythonInputReaderManager::InputReaderCallback bytes_len); reader.SetIsDone (true); } - break; case eInputReaderDone: - { - StreamString run_string; - char error_str[1024]; - const char *pty_slave_name = script_interpreter->m_embedded_thread_pty.GetSlaveName (error_str, sizeof (error_str)); - if (pty_slave_name != NULL && PyThreadState_GetDict() != NULL) { - ScriptInterpreterPython::Locker locker(script_interpreter, - ScriptInterpreterPython::Locker::AcquireLock | ScriptInterpreterPython::Locker::InitSession, - ScriptInterpreterPython::Locker::FreeAcquiredLock); - run_string.Printf ("run_one_line (%s, 'sys.stdin = save_stdin')", script_interpreter->m_dictionary_name.c_str()); - PyRun_SimpleString (run_string.GetData()); - run_string.Clear(); + StreamString run_string; + char error_str[1024]; + const char *pty_slave_name = script_interpreter->m_embedded_thread_pty.GetSlaveName (error_str, sizeof (error_str)); + if (pty_slave_name != NULL && PyThreadState_GetDict() != NULL) + { + ScriptInterpreterPython::Locker locker(script_interpreter, + ScriptInterpreterPython::Locker::AcquireLock, + ScriptInterpreterPython::Locker::FreeAcquiredLock); + run_string.Printf ("run_one_line (%s, 'sys.stdin = save_stdin; sys.stderr = save_stderr')", script_interpreter->m_dictionary_name.c_str()); + PyRun_SimpleString (run_string.GetData()); + run_string.Clear(); + } + // Restore terminal settings if they were validly saved + if (log) + log->Printf ("ScriptInterpreterPython::NonInteractiveInputReaderCallback, Done, closing down input reader."); - run_string.Printf ("run_one_line (%s, 'sys.stderr = save_stderr')", script_interpreter->m_dictionary_name.c_str()); - PyRun_SimpleString (run_string.GetData()); - run_string.Clear(); - } - } - - // Restore terminal settings if they were validly saved - if (log) - log->Printf ("ScriptInterpreterPython::NonInteractiveInputReaderCallback, Done, closing down input reader."); - - script_interpreter->RestoreTerminalState (); - - script_interpreter->m_embedded_thread_pty.CloseMasterFileDescriptor(); + script_interpreter->RestoreTerminalState (); + + script_interpreter->m_embedded_thread_pty.CloseMasterFileDescriptor(); + } break; } @@ -586,6 +582,10 @@ ScriptInterpreterPython::RestoreTerminalState () void ScriptInterpreterPython::LeaveSession () { + LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SCRIPT)); + if (log) + log->PutCString("ScriptInterpreterPython::LeaveSession()"); + // checking that we have a valid thread state - since we use our own threading and locking // in some (rare) cases during cleanup Python may end up believing we have no thread state // and PyImport_AddModule will crash if that is the case - since that seems to only happen @@ -610,14 +610,22 @@ ScriptInterpreterPython::LeaveSession () m_session_is_active = false; } -void +bool ScriptInterpreterPython::EnterSession (bool init_lldb_globals) { // If we have already entered the session, without having officially 'left' it, then there is no need to // 'enter' it again. - + LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SCRIPT)); if (m_session_is_active) - return; + { + if (log) + log->Printf("ScriptInterpreterPython::EnterSession(init_lldb_globals=%i) session is already active, returning without doing anything", init_lldb_globals); + return false; + } + + if (log) + log->Printf("ScriptInterpreterPython::EnterSession(init_lldb_globals=%i)", init_lldb_globals); + m_session_is_active = true; @@ -660,6 +668,8 @@ ScriptInterpreterPython::EnterSession (bool init_lldb_globals) if (PyErr_Occurred()) PyErr_Clear (); + + return true; } static PyObject* @@ -733,7 +743,7 @@ ScriptInterpreterPython::ExecuteOneLine (const char *command, CommandReturnObjec Locker locker(this, ScriptInterpreterPython::Locker::AcquireLock | ScriptInterpreterPython::Locker::InitSession | (options.GetSetLLDBGlobals() ? ScriptInterpreterPython::Locker::InitGlobals : 0), - ScriptInterpreterPython::Locker::FreeAcquiredLock | (options.GetSetLLDBGlobals() ? ScriptInterpreterPython::Locker::TearDownSession : 0)); + ScriptInterpreterPython::Locker::FreeAcquiredLock | ScriptInterpreterPython::Locker::TearDownSession); bool success = false; @@ -854,9 +864,7 @@ ScriptInterpreterPython::InputReaderCallback { ScriptInterpreterPython::Locker locker(script_interpreter, - ScriptInterpreterPython::Locker::AcquireLock - | ScriptInterpreterPython::Locker::InitSession - | ScriptInterpreterPython::Locker::InitGlobals, + ScriptInterpreterPython::Locker::AcquireLock | ScriptInterpreterPython::Locker::InitSession | ScriptInterpreterPython::Locker::InitGlobals, ScriptInterpreterPython::Locker::FreeAcquiredLock); } @@ -900,11 +908,9 @@ ScriptInterpreterPython::InputReaderCallback case eInputReaderReactivate: { - ScriptInterpreterPython::Locker locker(script_interpreter, - ScriptInterpreterPython::Locker::AcquireLock - | ScriptInterpreterPython::Locker::InitSession - | ScriptInterpreterPython::Locker::InitGlobals, - ScriptInterpreterPython::Locker::FreeAcquiredLock); + ScriptInterpreterPython::Locker locker (script_interpreter, + ScriptInterpreterPython::Locker::AcquireLock | ScriptInterpreterPython::Locker::InitSession, + ScriptInterpreterPython::Locker::FreeAcquiredLock); } break; @@ -1008,10 +1014,8 @@ ScriptInterpreterPython::ExecuteOneLineWithReturn (const char *in_string, { Locker locker(this, - ScriptInterpreterPython::Locker::AcquireLock - | ScriptInterpreterPython::Locker::InitSession - | (options.GetSetLLDBGlobals() ? ScriptInterpreterPython::Locker::InitGlobals : 0), - ScriptInterpreterPython::Locker::FreeAcquiredLock | (options.GetSetLLDBGlobals() ? ScriptInterpreterPython::Locker::TearDownSession : 0)); + ScriptInterpreterPython::Locker::AcquireLock | ScriptInterpreterPython::Locker::InitSession | (options.GetSetLLDBGlobals() ? ScriptInterpreterPython::Locker::InitGlobals : 0), + ScriptInterpreterPython::Locker::FreeAcquiredLock | ScriptInterpreterPython::Locker::TearDownSession); PyObject *py_return = NULL; PyObject *mainmod = PyImport_AddModule ("__main__"); @@ -1177,10 +1181,8 @@ ScriptInterpreterPython::ExecuteMultipleLines (const char *in_string, const Exec Locker locker(this, - ScriptInterpreterPython::Locker::AcquireLock - | ScriptInterpreterPython::Locker::InitSession - | (options.GetSetLLDBGlobals() ? ScriptInterpreterPython::Locker::InitGlobals : 0), - ScriptInterpreterPython::Locker::FreeAcquiredLock | (options.GetSetLLDBGlobals() ? ScriptInterpreterPython::Locker::TearDownSession : 0)); + ScriptInterpreterPython::Locker::AcquireLock | ScriptInterpreterPython::Locker::InitSession | (options.GetSetLLDBGlobals() ? ScriptInterpreterPython::Locker::InitGlobals : 0), + ScriptInterpreterPython::Locker::FreeAcquiredLock | ScriptInterpreterPython::Locker::TearDownSession); bool success = false; PyObject *py_return = NULL; @@ -1719,7 +1721,7 @@ ScriptInterpreterPython::GenerateTypeSynthClass (StringList &user_input, std::st } lldb::ScriptInterpreterObjectSP -ScriptInterpreterPython::CreateOSPlugin (const char *class_name, lldb::ProcessSP process_sp) +ScriptInterpreterPython::OSPlugin_CreatePluginObject (const char *class_name, lldb::ProcessSP process_sp) { if (class_name == NULL || class_name[0] == '\0') return lldb::ScriptInterpreterObjectSP(); @@ -1740,16 +1742,16 @@ ScriptInterpreterPython::CreateOSPlugin (const char *class_name, lldb::ProcessSP } lldb::ScriptInterpreterObjectSP -ScriptInterpreterPython::OSPlugin_QueryForRegisterInfo (lldb::ScriptInterpreterObjectSP object) +ScriptInterpreterPython::OSPlugin_RegisterInfo (lldb::ScriptInterpreterObjectSP os_plugin_object_sp) { Locker py_lock(this,Locker::AcquireLock,Locker::FreeLock); static char callee_name[] = "get_register_info"; - if (!object) + if (!os_plugin_object_sp) return lldb::ScriptInterpreterObjectSP(); - PyObject* implementor = (PyObject*)object->GetObject(); + PyObject* implementor = (PyObject*)os_plugin_object_sp->GetObject(); if (implementor == NULL || implementor == Py_None) return lldb::ScriptInterpreterObjectSP(); @@ -1799,16 +1801,16 @@ ScriptInterpreterPython::OSPlugin_QueryForRegisterInfo (lldb::ScriptInterpreterO } lldb::ScriptInterpreterObjectSP -ScriptInterpreterPython::OSPlugin_QueryForThreadsInfo (lldb::ScriptInterpreterObjectSP object) +ScriptInterpreterPython::OSPlugin_ThreadsInfo (lldb::ScriptInterpreterObjectSP os_plugin_object_sp) { Locker py_lock(this,Locker::AcquireLock,Locker::FreeLock); static char callee_name[] = "get_thread_info"; - if (!object) + if (!os_plugin_object_sp) return lldb::ScriptInterpreterObjectSP(); - PyObject* implementor = (PyObject*)object->GetObject(); + PyObject* implementor = (PyObject*)os_plugin_object_sp->GetObject(); if (implementor == NULL || implementor == Py_None) return lldb::ScriptInterpreterObjectSP(); @@ -1857,19 +1859,45 @@ ScriptInterpreterPython::OSPlugin_QueryForThreadsInfo (lldb::ScriptInterpreterOb return MakeScriptObject(py_return); } +// GetPythonValueFormatString provides a system independent type safe way to +// convert a variable's type into a python value format. Python value formats +// are defined in terms of builtin C types and could change from system to +// as the underlying typedef for uint* types, size_t, off_t and other values +// change. + +template <typename T> +const char *GetPythonValueFormatString(T t) +{ + assert(!"Unhandled type passed to GetPythonValueFormatString(T), make a specialization of GetPythonValueFormatString() to support this type."); + return NULL; +} +template <> const char *GetPythonValueFormatString (char *) { return "s"; } +template <> const char *GetPythonValueFormatString (char) { return "b"; } +template <> const char *GetPythonValueFormatString (unsigned char) { return "B"; } +template <> const char *GetPythonValueFormatString (short) { return "h"; } +template <> const char *GetPythonValueFormatString (unsigned short) { return "H"; } +template <> const char *GetPythonValueFormatString (int) { return "i"; } +template <> const char *GetPythonValueFormatString (unsigned int) { return "I"; } +template <> const char *GetPythonValueFormatString (long) { return "l"; } +template <> const char *GetPythonValueFormatString (unsigned long) { return "k"; } +template <> const char *GetPythonValueFormatString (long long) { return "L"; } +template <> const char *GetPythonValueFormatString (unsigned long long) { return "K"; } +template <> const char *GetPythonValueFormatString (float t) { return "f"; } +template <> const char *GetPythonValueFormatString (double t) { return "d"; } + lldb::ScriptInterpreterObjectSP -ScriptInterpreterPython::OSPlugin_QueryForRegisterContextData (lldb::ScriptInterpreterObjectSP object, - lldb::tid_t thread_id) +ScriptInterpreterPython::OSPlugin_RegisterContextData (lldb::ScriptInterpreterObjectSP os_plugin_object_sp, + lldb::tid_t tid) { Locker py_lock(this,Locker::AcquireLock,Locker::FreeLock); static char callee_name[] = "get_register_data"; - static char param_format[] = "l"; + static char *param_format = const_cast<char *>(GetPythonValueFormatString(tid)); - if (!object) + if (!os_plugin_object_sp) return lldb::ScriptInterpreterObjectSP(); - PyObject* implementor = (PyObject*)object->GetObject(); + PyObject* implementor = (PyObject*)os_plugin_object_sp->GetObject(); if (implementor == NULL || implementor == Py_None) return lldb::ScriptInterpreterObjectSP(); @@ -1906,8 +1934,72 @@ ScriptInterpreterPython::OSPlugin_QueryForRegisterContextData (lldb::ScriptInter Py_XDECREF(pmeth); // right now we know this function exists and is callable.. - PyObject* py_return = PyObject_CallMethod(implementor, callee_name, param_format, thread_id); + PyObject* py_return = PyObject_CallMethod(implementor, callee_name, param_format, tid); + + // if it fails, print the error but otherwise go on + if (PyErr_Occurred()) + { + PyErr_Print(); + PyErr_Clear(); + } + + return MakeScriptObject(py_return); +} +lldb::ScriptInterpreterObjectSP +ScriptInterpreterPython::OSPlugin_CreateThread (lldb::ScriptInterpreterObjectSP os_plugin_object_sp, + lldb::tid_t tid, + lldb::addr_t context) +{ + Locker py_lock(this,Locker::AcquireLock,Locker::FreeLock); + + static char callee_name[] = "create_thread"; + std::string param_format; + param_format += GetPythonValueFormatString(tid); + param_format += GetPythonValueFormatString(context); + + if (!os_plugin_object_sp) + return lldb::ScriptInterpreterObjectSP(); + + PyObject* implementor = (PyObject*)os_plugin_object_sp->GetObject(); + + if (implementor == NULL || implementor == Py_None) + return lldb::ScriptInterpreterObjectSP(); + + PyObject* pmeth = PyObject_GetAttrString(implementor, callee_name); + + if (PyErr_Occurred()) + { + PyErr_Clear(); + } + + if (pmeth == NULL || pmeth == Py_None) + { + Py_XDECREF(pmeth); + return lldb::ScriptInterpreterObjectSP(); + } + + if (PyCallable_Check(pmeth) == 0) + { + if (PyErr_Occurred()) + { + PyErr_Clear(); + } + + Py_XDECREF(pmeth); + return lldb::ScriptInterpreterObjectSP(); + } + + if (PyErr_Occurred()) + { + PyErr_Clear(); + } + + Py_XDECREF(pmeth); + + // right now we know this function exists and is callable.. + PyObject* py_return = PyObject_CallMethod(implementor, callee_name, ¶m_format[0], tid, context); + // if it fails, print the error but otherwise go on if (PyErr_Occurred()) { @@ -2651,8 +2743,8 @@ ScriptInterpreterPython::RunScriptBasedCommand(const char* impl_function, { Locker py_lock(this, - Locker::AcquireLock | Locker::InitSession | Locker::InitGlobals, - Locker::FreeLock | Locker::TearDownSession); + Locker::AcquireLock | Locker::InitSession, + Locker::FreeLock | Locker::TearDownSession); SynchronicityHandler synch_handler(debugger_sp, synchronicity); @@ -2697,8 +2789,9 @@ ScriptInterpreterPython::GetDocumentationForItem(const char* item, std::string& char* result_ptr = NULL; // Python is going to point this to valid data if ExecuteOneLineWithReturn returns successfully if (ExecuteOneLineWithReturn (command.c_str(), - ScriptInterpreter::eScriptReturnTypeCharStrOrNone, - &result_ptr, ScriptInterpreter::ExecuteScriptOptions().SetEnableIO(false) /*.SetSetLLDBGlobals(false)*/)) + ScriptInterpreter::eScriptReturnTypeCharStrOrNone, + &result_ptr, + ScriptInterpreter::ExecuteScriptOptions().SetEnableIO(false))) { if (result_ptr) dest.assign(result_ptr); |