summaryrefslogtreecommitdiffstats
path: root/lldb/source/Interpreter/ScriptInterpreterPython.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Interpreter/ScriptInterpreterPython.cpp')
-rw-r--r--lldb/source/Interpreter/ScriptInterpreterPython.cpp271
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, &param_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);
OpenPOWER on IntegriCloud