[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