diff options
author | Greg Clayton <gclayton@apple.com> | 2015-01-27 01:58:22 +0000 |
---|---|---|
committer | Greg Clayton <gclayton@apple.com> | 2015-01-27 01:58:22 +0000 |
commit | e507bce2deba996aad34b3adabf296493496d3de (patch) | |
tree | 17b83656bc7adebae392c6029f9b10f8d942f82f /lldb/source/Interpreter | |
parent | d649c0ad56237c66ce1bfdf349fcc4718031f663 (diff) | |
download | bcm5719-llvm-e507bce2deba996aad34b3adabf296493496d3de.tar.gz bcm5719-llvm-e507bce2deba996aad34b3adabf296493496d3de.zip |
Allow python command interpreter commands to be interruptable via CTRL+C.
<rdar://problem/17935601>
llvm-svn: 227163
Diffstat (limited to 'lldb/source/Interpreter')
-rw-r--r-- | lldb/source/Interpreter/CommandInterpreter.cpp | 7 | ||||
-rw-r--r-- | lldb/source/Interpreter/ScriptInterpreterPython.cpp | 49 |
2 files changed, 37 insertions, 19 deletions
diff --git a/lldb/source/Interpreter/CommandInterpreter.cpp b/lldb/source/Interpreter/CommandInterpreter.cpp index 2729c65525f..6318b80a29e 100644 --- a/lldb/source/Interpreter/CommandInterpreter.cpp +++ b/lldb/source/Interpreter/CommandInterpreter.cpp @@ -3229,6 +3229,13 @@ CommandInterpreter::IOHandlerInterrupt (IOHandler &io_handler) return true; // Don't do any updating when we are running } } + + ScriptInterpreter *script_interpreter = GetScriptInterpreter (false); + if (script_interpreter) + { + if (script_interpreter->Interrupt()) + return true; + } return false; } diff --git a/lldb/source/Interpreter/ScriptInterpreterPython.cpp b/lldb/source/Interpreter/ScriptInterpreterPython.cpp index ab151073f9e..719f966ace9 100644 --- a/lldb/source/Interpreter/ScriptInterpreterPython.cpp +++ b/lldb/source/Interpreter/ScriptInterpreterPython.cpp @@ -103,13 +103,14 @@ ScriptInterpreterPython::Locker::DoAcquireLock() m_GILState = PyGILState_Ensure(); if (log) log->Printf("Ensured PyGILState. Previous state = %slocked\n", m_GILState == PyGILState_UNLOCKED ? "un" : ""); - + // we need to save the thread state when we first start the command // because we might decide to interrupt it while some action is taking // place outside of Python (e.g. printing to screen, waiting for the network, ...) // in that case, _PyThreadState_Current will be NULL - and we would be unable // to set the asynchronous exception - not a desirable situation m_python_interpreter->SetThreadState (_PyThreadState_Current); + m_python_interpreter->IncrementLockCount(); return true; } @@ -128,6 +129,7 @@ ScriptInterpreterPython::Locker::DoFreeLock() if (log) log->Printf("Releasing PyGILState. Returning to state = %slocked\n", m_GILState == PyGILState_UNLOCKED ? "un" : ""); PyGILState_Release(m_GILState); + m_python_interpreter->DecrementLockCount(); return true; } @@ -166,6 +168,7 @@ ScriptInterpreterPython::ScriptInterpreterPython (CommandInterpreter &interprete m_session_is_active (false), m_pty_slave_is_open (false), m_valid_session (true), + m_lock_count (0), m_command_thread_state (nullptr) { @@ -817,24 +820,7 @@ public: virtual bool Interrupt () { - Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SCRIPT)); - - PyThreadState* state = _PyThreadState_Current; - if (!state) - state = m_python->GetThreadState(); - 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, static_cast<void *>(state)); - } - else if (log) - log->Printf("ScriptInterpreterPython::NonInteractiveInputReaderCallback, eInputReaderInterrupt, state = NULL"); - - return false; + return m_python->Interrupt(); } virtual void @@ -870,6 +856,31 @@ ScriptInterpreterPython::ExecuteInterpreterLoop () } bool +ScriptInterpreterPython::Interrupt() +{ + Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SCRIPT)); + + if (IsExecutingPython()) + { + PyThreadState* state = _PyThreadState_Current; + if (!state) + state = GetThreadState(); + if (state) + { + long tid = state->thread_id; + _PyThreadState_Current = state; + int num_threads = PyThreadState_SetAsyncExc(tid, PyExc_KeyboardInterrupt); + if (log) + log->Printf("ScriptInterpreterPython::Interrupt() sending PyExc_KeyboardInterrupt (tid = %li, num_threads = %i)...", tid, num_threads); + return true; + } + } + if (log) + log->Printf("ScriptInterpreterPython::Interrupt() python code not running, can't interrupt"); + return false; + +} +bool ScriptInterpreterPython::ExecuteOneLineWithReturn (const char *in_string, ScriptInterpreter::ScriptReturnType return_type, void *ret_value, |