[Lldb-commits] [lldb] r170612 - in /lldb/trunk: include/lldb/Host/Mutex.h include/lldb/Interpreter/ScriptInterpreterPython.h source/Host/common/Mutex.cpp source/Interpreter/ScriptInterpreterPython.cpp

Enrico Granata egranata at apple.com
Wed Dec 19 15:42:07 PST 2012


Author: enrico
Date: Wed Dec 19 17:42:07 2012
New Revision: 170612

URL: http://llvm.org/viewvc/llvm-project?rev=170612&view=rev
Log:
<rdar://problem/12446222>

Implement the ability for Python commands to be interrupted by pressing CTRL+C
Also add a new Mutex subclass that attempts to be helpful for debugging by logging actions performed on it

FYI of all interested - there is a separate deadlocking issue related to how LLDB dispatches CTRL+C that might cause LLDB to deadlock upon pressing CTRL+C while in a Python command.
This is not a regression, and was just previously masked by us not even trying to bail out of Python commands, so that it would not be clear from a user perspective whether we were
deadlocked or stuck in an inconsistent state within the Python interpreter.


Modified:
    lldb/trunk/include/lldb/Host/Mutex.h
    lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h
    lldb/trunk/source/Host/common/Mutex.cpp
    lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp

Modified: lldb/trunk/include/lldb/Host/Mutex.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Host/Mutex.h?rev=170612&r1=170611&r2=170612&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Host/Mutex.h (original)
+++ lldb/trunk/include/lldb/Host/Mutex.h Wed Dec 19 17:42:07 2012
@@ -193,6 +193,9 @@
     /// @return
     ///     The error code from \c pthread_mutex_lock().
     //------------------------------------------------------------------
+#ifdef LLDB_CONFIGURATION_DEBUG
+    virtual
+#endif
     int
     Lock();
 
@@ -280,6 +283,27 @@
     pthread_t m_thread_that_tried;
     std::string m_failure_message;
 };
+
+class LoggingMutex : public Mutex
+{
+public:
+    LoggingMutex() : Mutex(),m_locked(false)  {}
+    LoggingMutex(Mutex::Type type) : Mutex (type),m_locked(false) {}
+    
+    virtual
+    ~LoggingMutex() {}
+    
+    virtual int
+    Lock ();
+    
+    virtual int
+    Unlock ();
+    
+    virtual int
+    TryLock (const char *failure_message = NULL);
+protected:
+    bool m_locked;
+};
 #endif
 
 } // namespace lldb_private

Modified: lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h?rev=170612&r1=170611&r2=170612&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h (original)
+++ lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h Wed Dec 19 17:42:07 2012
@@ -366,6 +366,7 @@
     bool m_session_is_active;
     bool m_pty_slave_is_open;
     bool m_valid_session;
+    PyThreadState *m_command_thread_state;
 };
 } // namespace lldb_private
 

Modified: lldb/trunk/source/Host/common/Mutex.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/common/Mutex.cpp?rev=170612&r1=170611&r2=170612&view=diff
==============================================================================
--- lldb/trunk/source/Host/common/Mutex.cpp (original)
+++ lldb/trunk/source/Host/common/Mutex.cpp Wed Dec 19 17:42:07 2012
@@ -27,6 +27,7 @@
 // Enable extra mutex error checking
 #ifdef LLDB_CONFIGURATION_DEBUG
 #define ENABLE_MUTEX_ERROR_CHECKING 1
+#include <inttypes.h>
 #endif
 
 #if ENABLE_MUTEX_ERROR_CHECKING
@@ -352,6 +353,38 @@
     assert (m_failure_message.empty());
     return Mutex::Unlock();
 }
+
+int
+LoggingMutex::Lock ()
+{
+    printf("locking mutex %p by [%4.4" PRIx64 "/%4.4" PRIx64 "]...", this, Host::GetCurrentProcessID(), Host::GetCurrentThreadID());
+    int x = Mutex::Lock();
+    m_locked = true;
+    printf("%d\n",x);
+    return x;
+}
+
+int
+LoggingMutex::Unlock ()
+{
+    printf("unlocking mutex %p by [%4.4" PRIx64 "/%4.4" PRIx64 "]...", this, Host::GetCurrentProcessID(), Host::GetCurrentThreadID());
+    int x = Mutex::Unlock();
+    m_locked = false;
+    printf("%d\n",x);
+    return x;
+}
+
+int
+LoggingMutex::TryLock (const char *failure_message)
+{
+    printf("trylocking mutex %p by [%4.4" PRIx64 "/%4.4" PRIx64 "]...", this, Host::GetCurrentProcessID(), Host::GetCurrentThreadID());
+    int x = Mutex::TryLock(failure_message);
+    if (x == 0)
+        m_locked = true;
+    printf("%d\n",x);
+    return x;
+}
+
 #endif
-    
+
 

Modified: lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp?rev=170612&r1=170611&r2=170612&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp (original)
+++ lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp Wed Dec 19 17:42:07 2012
@@ -371,7 +371,22 @@
             break;
             
         case eInputReaderInterrupt:
-            reader.SetIsDone(true);
+        {
+            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");
+        }
             break;
             
         case eInputReaderEndOfFile:
@@ -446,7 +461,8 @@
     m_dictionary_name (interpreter.GetDebugger().GetInstanceName().AsCString()),
     m_terminal_state (),
     m_session_is_active (false),
-    m_valid_session (true)
+    m_valid_session (true),
+    m_command_thread_state (NULL)
 {
 
     static int g_initialized = false;
@@ -2643,8 +2659,16 @@
         Locker py_lock(this,
                        Locker::AcquireLock | Locker::InitSession | Locker::InitGlobals,
                        Locker::FreeLock | Locker::TearDownSession);
+
         SynchronicityHandler synch_handler(debugger_sp,
                                            synchronicity);
+
+        // 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_command_thread_state = _PyThreadState_Current;
         
         PythonInputReaderManager py_input(this);
         





More information about the lldb-commits mailing list