summaryrefslogtreecommitdiffstats
path: root/lldb/source/Interpreter
diff options
context:
space:
mode:
authorGreg Clayton <gclayton@apple.com>2015-01-27 01:58:22 +0000
committerGreg Clayton <gclayton@apple.com>2015-01-27 01:58:22 +0000
commite507bce2deba996aad34b3adabf296493496d3de (patch)
tree17b83656bc7adebae392c6029f9b10f8d942f82f /lldb/source/Interpreter
parentd649c0ad56237c66ce1bfdf349fcc4718031f663 (diff)
downloadbcm5719-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.cpp7
-rw-r--r--lldb/source/Interpreter/ScriptInterpreterPython.cpp49
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,
OpenPOWER on IntegriCloud