[Lldb-commits] [lldb] r207816 - Fixed CTRL+C related issues:

Greg Clayton gclayton at apple.com
Thu May 1 17:45:31 PDT 2014


Author: gclayton
Date: Thu May  1 19:45:31 2014
New Revision: 207816

URL: http://llvm.org/viewvc/llvm-project?rev=207816&view=rev
Log:
Fixed CTRL+C related issues:
- CTRL+C wasn't clearing the command in lldb
- CTRL+C doesn't work in python macros in lldb
- Ctrl+C no longer interrupts the running process that you attach to

<rdar://problem/15949205> 
<rdar://problem/16778652> 
<rdar://problem/16774411>


Modified:
    lldb/trunk/include/lldb/Core/ConnectionFileDescriptor.h
    lldb/trunk/include/lldb/Core/IOHandler.h
    lldb/trunk/include/lldb/Host/Editline.h
    lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h
    lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h
    lldb/trunk/include/lldb/lldb-enumerations.h
    lldb/trunk/source/Core/Communication.cpp
    lldb/trunk/source/Core/ConnectionFileDescriptor.cpp
    lldb/trunk/source/Core/IOHandler.cpp
    lldb/trunk/source/Host/common/Editline.cpp
    lldb/trunk/source/Interpreter/CommandInterpreter.cpp
    lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp
    lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
    lldb/trunk/source/Target/Process.cpp

Modified: lldb/trunk/include/lldb/Core/ConnectionFileDescriptor.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ConnectionFileDescriptor.h?rev=207816&r1=207815&r2=207816&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/ConnectionFileDescriptor.h (original)
+++ lldb/trunk/include/lldb/Core/ConnectionFileDescriptor.h Thu May  1 19:45:31 2014
@@ -77,6 +77,12 @@ public:
     uint16_t
     GetBoundPort (uint32_t timeout_sec);
 
+    lldb::ConnectionStatus
+    BytesAvailable (uint32_t timeout_usec, Error *error_ptr);
+
+    bool
+    InterruptRead ();
+
 protected:
 
     typedef enum
@@ -91,9 +97,6 @@ protected:
     
     void
     CloseCommandPipe ();
-
-    lldb::ConnectionStatus
-    BytesAvailable (uint32_t timeout_usec, Error *error_ptr);
     
     lldb::ConnectionStatus
     SocketListen (const char *host_and_port, Error *error_ptr);

Modified: lldb/trunk/include/lldb/Core/IOHandler.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/IOHandler.h?rev=207816&r1=207815&r2=207816&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/IOHandler.h (original)
+++ lldb/trunk/include/lldb/Core/IOHandler.h Thu May  1 19:45:31 2014
@@ -73,7 +73,7 @@ namespace lldb_private {
         // Called when CTRL+C is pressed which usually causes
         // Debugger::DispatchInputInterrupt to be called.
         
-        virtual void
+        virtual bool
         Interrupt () = 0;
         
         virtual void
@@ -304,11 +304,22 @@ namespace lldb_private {
         
         
         virtual ConstString
-        GetControlSequence (char ch)
+        IOHandlerGetControlSequence (char ch)
         {
             return ConstString();
         }
         
+        //------------------------------------------------------------------
+        // Intercept the IOHandler::Interrupt() calls and do something.
+        //
+        // Return true if the interrupt was handled, false if the IOHandler
+        // should continue to try handle the interrupt itself.
+        //------------------------------------------------------------------
+        virtual bool
+        IOHandlerInterrupt (IOHandler &io_handler)
+        {
+            return false;
+        }
     protected:
         Completion m_completion; // Support for common builtin completions
         bool m_io_handler_done;
@@ -338,7 +349,7 @@ namespace lldb_private {
         }
         
         virtual ConstString
-        GetControlSequence (char ch)
+        IOHandlerGetControlSequence (char ch)
         {
             if (ch == 'd')
                 return ConstString (m_end_line + "\n");
@@ -409,7 +420,7 @@ namespace lldb_private {
         virtual void
         Cancel ();
 
-        virtual void
+        virtual bool
         Interrupt ();
         
         virtual void
@@ -425,7 +436,7 @@ namespace lldb_private {
         virtual ConstString
         GetControlSequence (char ch)
         {
-            return m_delegate.GetControlSequence (ch);
+            return m_delegate.IOHandlerGetControlSequence (ch);
         }
 
         virtual const char *
@@ -435,10 +446,10 @@ namespace lldb_private {
         SetPrompt (const char *prompt);
 
         bool
-        GetLine (std::string &line);
+        GetLine (std::string &line, bool &interrupted);
         
         bool
-        GetLines (StringList &lines);
+        GetLines (StringList &lines, bool &interrupted);
         
         void
         SetBaseLineNumber (uint32_t line);
@@ -523,7 +534,7 @@ namespace lldb_private {
         virtual void
         Cancel ();
 
-        virtual void
+        virtual bool
         Interrupt ();
         
         virtual void
@@ -557,8 +568,8 @@ namespace lldb_private {
         virtual void
         Refresh ();
         
-        virtual void
-        Interrupt ();
+        virtual bool
+        HandleInterrupt ();
         
         virtual void
         GotEOF();

Modified: lldb/trunk/include/lldb/Host/Editline.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Host/Editline.h?rev=207816&r1=207815&r2=207816&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Host/Editline.h (original)
+++ lldb/trunk/include/lldb/Host/Editline.h Thu May  1 19:45:31 2014
@@ -23,6 +23,7 @@
 #include <string>
 #include <vector>
 
+#include "lldb/Core/ConnectionFileDescriptor.h"
 #include "lldb/Host/Condition.h"
 #include "lldb/Host/FileSpec.h"
 #include "lldb/Host/Mutex.h"
@@ -70,10 +71,13 @@ public:
     ~Editline();
 
     Error
-    GetLine (std::string &line);
+    GetLine (std::string &line,
+             bool &interrupted);
 
     Error
-    GetLines (const std::string &end_line, StringList &lines);
+    GetLines (const std::string &end_line,
+              StringList &lines,
+              bool &interrupted);
 
     bool
     LoadHistory ();
@@ -102,7 +106,7 @@ public:
     void
     Refresh();
 
-    void
+    bool
     Interrupt ();
 
     void
@@ -203,6 +207,7 @@ private:
     uint32_t m_line_offset;
     uint32_t m_lines_curr_line;
     uint32_t m_lines_max_line;
+    ConnectionFileDescriptor m_file;
     bool m_prompt_with_line_numbers;
     bool m_getting_line;
     bool m_got_eof;    // Set to true when we detect EOF

Modified: lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h?rev=207816&r1=207815&r2=207816&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h (original)
+++ lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h Thu May  1 19:45:31 2014
@@ -479,12 +479,15 @@ protected:
                             std::string &line);
 
     virtual ConstString
-    GetControlSequence (char ch)
+    IOHandlerGetControlSequence (char ch)
     {
         if (ch == 'd')
             return ConstString("quit\n");
         return ConstString();
     }
+    
+    virtual bool
+    IOHandlerInterrupt (IOHandler &io_handler);
 
     size_t
     GetProcessOutput ();

Modified: lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h?rev=207816&r1=207815&r2=207816&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h (original)
+++ lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h Thu May  1 19:45:31 2014
@@ -24,6 +24,8 @@
 #include "lldb/Interpreter/PythonDataObjects.h"
 #include "lldb/Host/Terminal.h"
 
+class IOHandlerPythonInterpreter;
+
 namespace lldb_private {
     
 class ScriptInterpreterPython :
@@ -282,6 +284,19 @@ public:
     }
 
     
+    PyThreadState *
+    GetThreadState()
+    {
+        return m_command_thread_state;
+    }
+
+    void
+    SetThreadState (PyThreadState *s)
+    {
+        if (s)
+            m_command_thread_state = s;
+    }
+
     //----------------------------------------------------------------------
     // IOHandlerDelegate
     //----------------------------------------------------------------------
@@ -399,7 +414,7 @@ public:
 //    	FILE*                    m_tmp_fh;
         PyGILState_STATE         m_GILState;
 	};
-private:
+protected:
 
     enum ActiveIOHandler {
         eIOHandlerNone,

Modified: lldb/trunk/include/lldb/lldb-enumerations.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-enumerations.h?rev=207816&r1=207815&r2=207816&view=diff
==============================================================================
--- lldb/trunk/include/lldb/lldb-enumerations.h (original)
+++ lldb/trunk/include/lldb/lldb-enumerations.h Thu May  1 19:45:31 2014
@@ -209,7 +209,8 @@ namespace lldb {
         eConnectionStatusError,           // Check GetError() for details
         eConnectionStatusTimedOut,        // Request timed out
         eConnectionStatusNoConnection,    // No connection
-        eConnectionStatusLostConnection   // Lost connection while connected to a valid connection
+        eConnectionStatusLostConnection,  // Lost connection while connected to a valid connection
+        eConnectionStatusInterrupted      // Interrupted read
     } ConnectionStatus;
 
     typedef enum ErrorType

Modified: lldb/trunk/source/Core/Communication.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Communication.cpp?rev=207816&r1=207815&r2=207816&view=diff
==============================================================================
--- lldb/trunk/source/Core/Communication.cpp (original)
+++ lldb/trunk/source/Core/Communication.cpp Thu May  1 19:45:31 2014
@@ -382,6 +382,8 @@ Communication::ReadThread (lldb::thread_
              break;
         case eConnectionStatusNoConnection:     // No connection
         case eConnectionStatusLostConnection:   // Lost connection while connected to a valid connection
+        case eConnectionStatusInterrupted:      // Interrupted
+
             done = true;
             // Fall through...
         case eConnectionStatusError:            // Check GetError() for details
@@ -433,6 +435,7 @@ Communication::ConnectionStatusAsCString
     case eConnectionStatusNoConnection:   return "no connection";
     case eConnectionStatusLostConnection: return "lost connection";
     case eConnectionStatusEndOfFile:      return "end of file";
+    case eConnectionStatusInterrupted:    return "interrupted";
     }
 
     static char unknown_state_string[64];

Modified: lldb/trunk/source/Core/ConnectionFileDescriptor.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ConnectionFileDescriptor.cpp?rev=207816&r1=207815&r2=207816&view=diff
==============================================================================
--- lldb/trunk/source/Core/ConnectionFileDescriptor.cpp (original)
+++ lldb/trunk/source/Core/ConnectionFileDescriptor.cpp Thu May  1 19:45:31 2014
@@ -361,6 +361,14 @@ ConnectionFileDescriptor::Connect (const
     return eConnectionStatusError;
 }
 
+bool
+ConnectionFileDescriptor::InterruptRead()
+{
+    if (m_pipe_write != -1 )
+        return write (m_pipe_write, "i", 1) == 1;
+    return false;
+}
+
 ConnectionStatus
 ConnectionFileDescriptor::Disconnect (Error *error_ptr)
 {
@@ -390,7 +398,7 @@ ConnectionFileDescriptor::Disconnect (Er
     m_shutting_down = true;
 
     Mutex::Locker locker;
-    bool got_lock= locker.TryLock (m_mutex);
+    bool got_lock = locker.TryLock (m_mutex);
 
     if (!got_lock)
     {
@@ -839,14 +847,19 @@ ConnectionFileDescriptor::BytesAvailable
                     {
                         bytes_read = ::read (pipe_fd, buffer, sizeof(buffer));
                     } while (bytes_read < 0 && errno == EINTR);
-                    assert (bytes_read == 1 && buffer[0] == 'q');
-
-                    if (log)
-                        log->Printf("%p ConnectionFileDescriptor::BytesAvailable() got data: %*s from the command channel.",
-                                    static_cast<void*>(this),
-                                    static_cast<int>(bytes_read), buffer);
-
-                    return eConnectionStatusEndOfFile;
+                    
+                    switch (buffer[0])
+                    {
+                    case 'q':
+                        if (log)
+                            log->Printf("%p ConnectionFileDescriptor::BytesAvailable() got data: %*s from the command channel.",
+                                        static_cast<void*>(this),
+                                        static_cast<int>(bytes_read), buffer);
+                        return eConnectionStatusEndOfFile;
+                    case 'i':
+                        // Interrupt the current read
+                        return eConnectionStatusInterrupted;
+                    }
                 }
             }
         }

Modified: lldb/trunk/source/Core/IOHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/IOHandler.cpp?rev=207816&r1=207815&r2=207816&view=diff
==============================================================================
--- lldb/trunk/source/Core/IOHandler.cpp (original)
+++ lldb/trunk/source/Core/IOHandler.cpp Thu May  1 19:45:31 2014
@@ -378,11 +378,11 @@ IOHandlerEditline::~IOHandlerEditline ()
 
 
 bool
-IOHandlerEditline::GetLine (std::string &line)
+IOHandlerEditline::GetLine (std::string &line, bool &interrupted)
 {
     if (m_editline_ap)
     {
-        return m_editline_ap->GetLine(line).Success();
+        return m_editline_ap->GetLine(line, interrupted).Success();
     }
     else
     {
@@ -518,13 +518,13 @@ IOHandlerEditline::SetBaseLineNumber (ui
     
 }
 bool
-IOHandlerEditline::GetLines (StringList &lines)
+IOHandlerEditline::GetLines (StringList &lines, bool &interrupted)
 {
     bool success = false;
     if (m_editline_ap)
     {
         std::string end_token;
-        success = m_editline_ap->GetLines(end_token, lines).Success();
+        success = m_editline_ap->GetLines(end_token, lines, interrupted).Success();
     }
     else
     {
@@ -541,11 +541,19 @@ IOHandlerEditline::GetLines (StringList
                     ::fprintf(out, "%u", m_base_line_number + (uint32_t)lines.GetSize());
             }
             
-            if (GetLine(line))
+            bool interrupted = false;
+            if (GetLine(line, interrupted))
             {
-                lines.AppendString(line);
-                Error error;
-                lines_status = m_delegate.IOHandlerLinesUpdated(*this, lines, lines.GetSize() - 1, error);
+                if (interrupted)
+                {
+                    lines_status = LineStatus::Done;
+                }
+                else
+                {
+                    lines.AppendString(line);
+                    Error error;
+                    lines_status = m_delegate.IOHandlerLinesUpdated(*this, lines, lines.GetSize() - 1, error);
+                }
             }
             else
             {
@@ -566,13 +574,21 @@ IOHandlerEditline::Run ()
     std::string line;
     while (IsActive())
     {
+        bool interrupted = false;
         if (m_multi_line)
         {
             StringList lines;
-            if (GetLines (lines))
+            if (GetLines (lines, interrupted))
             {
-                line = lines.CopyList();
-                m_delegate.IOHandlerInputComplete(*this, line);
+                if (interrupted)
+                {
+                    m_done = true;
+                }
+                else
+                {
+                    line = lines.CopyList();
+                    m_delegate.IOHandlerInputComplete(*this, line);
+                }
             }
             else
             {
@@ -581,9 +597,10 @@ IOHandlerEditline::Run ()
         }
         else
         {
-            if (GetLine(line))
+            if (GetLine(line, interrupted))
             {
-                m_delegate.IOHandlerInputComplete(*this, line);
+                if (!interrupted)
+                    m_delegate.IOHandlerInputComplete(*this, line);
             }
             else
             {
@@ -628,11 +645,16 @@ IOHandlerEditline::Cancel ()
         m_editline_ap->Interrupt ();
 }
 
-void
+bool
 IOHandlerEditline::Interrupt ()
 {
+    // Let the delgate handle it first
+    if (m_delegate.IOHandlerInterrupt(*this))
+        return true;
+
     if (m_editline_ap)
-        m_editline_ap->Interrupt();
+        return m_editline_ap->Interrupt();
+    return false;
 }
 
 void
@@ -5454,9 +5476,10 @@ IOHandlerCursesGUI::Cancel ()
 {
 }
 
-void
+bool
 IOHandlerCursesGUI::Interrupt ()
 {
+    return false;
 }
 
 

Modified: lldb/trunk/source/Host/common/Editline.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/common/Editline.cpp?rev=207816&r1=207815&r2=207816&view=diff
==============================================================================
--- lldb/trunk/source/Host/common/Editline.cpp (original)
+++ lldb/trunk/source/Host/common/Editline.cpp Thu May  1 19:45:31 2014
@@ -174,6 +174,7 @@ Editline::Editline (const char *prog,
     m_line_offset (0),
     m_lines_curr_line (0),
     m_lines_max_line (0),
+    m_file (fileno(fin), false),
     m_prompt_with_line_numbers (false),
     m_getting_line (false),
     m_got_eof (false),
@@ -190,6 +191,7 @@ Editline::Editline (const char *prog,
     {
         m_editline = ::el_init("lldb-tmp", fin, fout, ferr);
     }
+    
     if (prompt && prompt[0])
         SetPrompt (prompt);
 
@@ -324,7 +326,7 @@ Editline::PrivateGetLine(std::string &li
             llvm::StringRef line_ref (line_cstr);
             line_ref = line_ref.rtrim("\n\r");
             
-            if (!line_ref.empty())
+            if (!line_ref.empty() && !m_interrupted)
             {
                 // We didn't strip the newlines, we just adjusted the length, and
                 // we want to add the history item with the newlines
@@ -345,9 +347,10 @@ Editline::PrivateGetLine(std::string &li
 
 
 Error
-Editline::GetLine(std::string &line)
+Editline::GetLine(std::string &line, bool &interrupted)
 {
     Error error;
+    interrupted = false;
     line.clear();
 
     // Set arrow key bindings for up and down arrows for single line
@@ -371,6 +374,8 @@ Editline::GetLine(std::string &line)
         m_getting_line = false;
     }
 
+    interrupted = m_interrupted;
+
     if (m_got_eof && line.empty())
     {
         // Only set the error if we didn't get an error back from PrivateGetLine()
@@ -397,9 +402,10 @@ Editline::Push (const char *bytes, size_
 
 
 Error
-Editline::GetLines(const std::string &end_line, StringList &lines)
+Editline::GetLines(const std::string &end_line, StringList &lines, bool &interrupted)
 {
     Error error;
+    interrupted = false;
     if (m_getting_line)
     {
         error.SetErrorString("already getting a line");
@@ -436,6 +442,11 @@ Editline::GetLines(const std::string &en
         {
             line_status = LineStatus::Error;
         }
+        else if (m_interrupted)
+        {
+            interrupted = true;
+            line_status = LineStatus::Done;
+        }
         else
         {
             switch (m_lines_command)
@@ -500,7 +511,7 @@ Editline::GetLines(const std::string &en
 
     // If we have a callback, call it one more time to let the
     // user know the lines are complete
-    if (m_line_complete_callback)
+    if (m_line_complete_callback && !interrupted)
         m_line_complete_callback (this,
                                   lines,
                                   UINT32_MAX,
@@ -755,39 +766,65 @@ Editline::GetCharFromInputFileCallback (
     Editline *editline = GetClientData (e);
     if (editline && editline->m_got_eof == false)
     {
+        FILE *f = editline->GetInputFile();
+        if (f == NULL)
+        {
+            editline->m_got_eof = true;
+            return 0;
+        }
+        
+        
         while (1)
         {
-            errno = 0;
-            char ch = ::fgetc(editline->GetInputFile());
-            if (ch == '\x04')
+            lldb::ConnectionStatus status = eConnectionStatusSuccess;
+            char ch = 0;
+            if (editline->m_file.Read(&ch, 1, UINT32_MAX, status, NULL))
             {
-                // Only turn a CTRL+D into a EOF if we receive the
-                // CTRL+D an empty line, otherwise it will forward
-                // delete the character at the cursor
-                const LineInfo *line_info = ::el_line(e);
-                if (line_info != NULL &&
-                    line_info->buffer == line_info->cursor &&
-                    line_info->cursor == line_info->lastchar)
+                if (ch == '\x04')
                 {
-                    ch = EOF;
-                    errno = 0;
+                    // Only turn a CTRL+D into a EOF if we receive the
+                    // CTRL+D an empty line, otherwise it will forward
+                    // delete the character at the cursor
+                    const LineInfo *line_info = ::el_line(e);
+                    if (line_info != NULL &&
+                        line_info->buffer == line_info->cursor &&
+                        line_info->cursor == line_info->lastchar)
+                    {
+                        ch = EOF;
+                    }
                 }
-            }
-        
-            if (ch == EOF)
-            {
-                if (errno == EINTR)
-                    continue;
-                else
+            
+                if (ch == EOF)
                 {
                     editline->m_got_eof = true;
                     break;
                 }
+                else
+                {
+                    *c = ch;
+                    return 1;
+                }
             }
             else
             {
-                *c = ch;
-                return 1;
+                switch (status)
+                {
+                    case eConnectionStatusInterrupted:
+                        editline->m_interrupted = true;
+                        *c = '\n';
+                        return 1;
+
+                    case eConnectionStatusSuccess:         // Success
+                        break;
+                        
+                    case eConnectionStatusError:           // Check GetError() for details
+                    case eConnectionStatusTimedOut:        // Request timed out
+                    case eConnectionStatusEndOfFile:       // End-of-file encountered
+                    case eConnectionStatusNoConnection:    // No connection
+                    case eConnectionStatusLostConnection:  // Lost connection while connected to a valid connection
+                        editline->m_got_eof = true;
+                        break;
+                }
             }
         }
     }
@@ -813,10 +850,11 @@ Editline::Refresh()
     ::el_set (m_editline, EL_REFRESH);
 }
 
-void
+bool
 Editline::Interrupt ()
 {
     m_interrupted = true;
     if (m_getting_line || m_lines_curr_line > 0)
-        el_insertstr(m_editline, "\n"); // True to force the line to complete itself so we get exit from el_gets()
+        return m_file.InterruptRead();
+    return false; // Interrupt not handled as we weren't getting a line or lines
 }

Modified: lldb/trunk/source/Interpreter/CommandInterpreter.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/CommandInterpreter.cpp?rev=207816&r1=207815&r2=207816&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/CommandInterpreter.cpp (original)
+++ lldb/trunk/source/Interpreter/CommandInterpreter.cpp Thu May  1 19:45:31 2014
@@ -44,6 +44,7 @@
 
 #include "lldb/Core/Debugger.h"
 #include "lldb/Core/Log.h"
+#include "lldb/Core/State.h"
 #include "lldb/Core/Stream.h"
 #include "lldb/Core/StreamFile.h"
 #include "lldb/Core/Timer.h"
@@ -3051,6 +3052,24 @@ CommandInterpreter::IOHandlerInputComple
     }
 }
 
+bool
+CommandInterpreter::IOHandlerInterrupt (IOHandler &io_handler)
+{
+    ExecutionContext exe_ctx (GetExecutionContext());
+    Process *process = exe_ctx.GetProcessPtr();
+    
+    if (process)
+    {
+        StateType state = process->GetState();
+        if (StateIsRunningState(state))
+        {
+            process->Halt();
+            return true; // Don't do any updating when we are running
+        }
+    }
+    return false;
+}
+
 void
 CommandInterpreter::GetLLDBCommandsFromIOHandler (const char *prompt,
                                                   IOHandlerDelegate &delegate,

Modified: lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp?rev=207816&r1=207815&r2=207816&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp (original)
+++ lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp Thu May  1 19:45:31 2014
@@ -93,6 +93,13 @@ 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);
     return true;
 }
 
@@ -781,10 +788,27 @@ public:
         
     }
 
-    virtual void
+    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,state);
+        }
+        else if (log)
+            log->Printf("ScriptInterpreterPython::NonInteractiveInputReaderCallback, eInputReaderInterrupt, state = NULL");
+
+        return false;
     }
     
     virtual void
@@ -2433,15 +2457,6 @@ ScriptInterpreterPython::RunScriptBasedC
         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);
-        
         ret_val = g_swig_call_command       (impl_function,
                                              m_dictionary_name.c_str(),
                                              debugger_sp,

Modified: lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp?rev=207816&r1=207815&r2=207816&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp (original)
+++ lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp Thu May  1 19:45:31 2014
@@ -259,6 +259,7 @@ CommunicationKDP::WaitForPacketWithTimeo
         {
             switch (status)
             {
+            case eConnectionStatusInterrupted:
             case eConnectionStatusTimedOut:
                 timed_out = true;
                 break;

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp?rev=207816&r1=207815&r2=207816&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp Thu May  1 19:45:31 2014
@@ -321,6 +321,7 @@ GDBRemoteCommunication::WaitForPacketWit
             switch (status)
             {
             case eConnectionStatusTimedOut:
+            case eConnectionStatusInterrupted:
                 timed_out = true;
                 break;
             case eConnectionStatusSuccess:

Modified: lldb/trunk/source/Target/Process.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Process.cpp?rev=207816&r1=207815&r2=207816&view=diff
==============================================================================
--- lldb/trunk/source/Target/Process.cpp (original)
+++ lldb/trunk/source/Target/Process.cpp Thu May  1 19:45:31 2014
@@ -4935,7 +4935,7 @@ public:
         m_pipe_write.Write (&ch, n);
     }
 
-    virtual void
+    virtual bool
     Interrupt ()
     {
 #ifdef _MSC_VER
@@ -4953,6 +4953,7 @@ public:
         char ch = 'i'; // Send 'i' for interrupt
         m_pipe_write.Write (&ch, n);
 #endif
+        return true;
     }
     
     virtual void





More information about the lldb-commits mailing list