[Lldb-commits] [lldb] r227163 - Allow python command interpreter commands to be interruptable via CTRL+C.
Greg Clayton
gclayton at apple.com
Mon Jan 26 17:58:23 PST 2015
Author: gclayton
Date: Mon Jan 26 19:58:22 2015
New Revision: 227163
URL: http://llvm.org/viewvc/llvm-project?rev=227163&view=rev
Log:
Allow python command interpreter commands to be interruptable via CTRL+C.
<rdar://problem/17935601>
Modified:
lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h
lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h
lldb/trunk/source/Interpreter/CommandInterpreter.cpp
lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp
Modified: lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h?rev=227163&r1=227162&r2=227163&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h (original)
+++ lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h Mon Jan 26 19:58:22 2015
@@ -240,7 +240,13 @@ public:
bool m_set_lldb_globals;
bool m_maskout_errors;
};
-
+
+ virtual bool
+ Interrupt()
+ {
+ return false;
+ }
+
virtual bool
ExecuteOneLine (const char *command,
CommandReturnObject *result,
Modified: lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h?rev=227163&r1=227162&r2=227163&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h (original)
+++ lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h Mon Jan 26 19:58:22 2015
@@ -41,6 +41,9 @@ public:
~ScriptInterpreterPython ();
bool
+ Interrupt() override;
+
+ bool
ExecuteOneLine (const char *command,
CommandReturnObject *result,
const ExecuteScriptOptions &options = ExecuteScriptOptions());
@@ -448,6 +451,26 @@ public:
};
protected:
+ uint32_t
+ IsExecutingPython () const
+ {
+ return m_lock_count > 0;
+ }
+
+ uint32_t
+ IncrementLockCount()
+ {
+ return ++m_lock_count;
+ }
+
+ uint32_t
+ DecrementLockCount()
+ {
+ if (m_lock_count > 0)
+ --m_lock_count;
+ return m_lock_count;
+ }
+
enum ActiveIOHandler {
eIOHandlerNone,
eIOHandlerBreakpoint,
@@ -480,6 +503,7 @@ protected:
bool m_session_is_active;
bool m_pty_slave_is_open;
bool m_valid_session;
+ uint32_t m_lock_count;
PyThreadState *m_command_thread_state;
};
} // namespace lldb_private
Modified: lldb/trunk/source/Interpreter/CommandInterpreter.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/CommandInterpreter.cpp?rev=227163&r1=227162&r2=227163&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/CommandInterpreter.cpp (original)
+++ lldb/trunk/source/Interpreter/CommandInterpreter.cpp Mon Jan 26 19:58:22 2015
@@ -3229,6 +3229,13 @@ CommandInterpreter::IOHandlerInterrupt (
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;
}
Modified: lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp?rev=227163&r1=227162&r2=227163&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp (original)
+++ lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp Mon Jan 26 19:58:22 2015
@@ -103,13 +103,14 @@ ScriptInterpreterPython::Locker::DoAcqui
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::DoFreeL
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::ScriptInterpret
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::ExecuteInterpre
}
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,
More information about the lldb-commits
mailing list