[Lldb-commits] [lldb] r119837 - in /lldb/trunk: include/lldb/ include/lldb/API/ include/lldb/Core/ source/API/ source/Commands/ source/Core/ source/Interpreter/ source/Plugins/Process/gdb-remote/ source/Target/ tools/driver/

Caroline Tice ctice at apple.com
Fri Nov 19 12:47:55 PST 2010


Author: ctice
Date: Fri Nov 19 14:47:54 2010
New Revision: 119837

URL: http://llvm.org/viewvc/llvm-project?rev=119837&view=rev
Log:
Add the ability to catch and do the right thing with Interrupts (often control-c)
and end-of-file (often control-d).


Modified:
    lldb/trunk/include/lldb/API/SBDebugger.h
    lldb/trunk/include/lldb/Core/Communication.h
    lldb/trunk/include/lldb/Core/Debugger.h
    lldb/trunk/include/lldb/lldb-enumerations.h
    lldb/trunk/source/API/SBDebugger.cpp
    lldb/trunk/source/Commands/CommandObjectBreakpointCommand.cpp
    lldb/trunk/source/Commands/CommandObjectExpression.cpp
    lldb/trunk/source/Core/Communication.cpp
    lldb/trunk/source/Core/ConnectionFileDescriptor.cpp
    lldb/trunk/source/Core/Debugger.cpp
    lldb/trunk/source/Core/InputReader.cpp
    lldb/trunk/source/Interpreter/CommandInterpreter.cpp
    lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
    lldb/trunk/source/Target/Process.cpp
    lldb/trunk/tools/driver/Driver.cpp
    lldb/trunk/tools/driver/IOChannel.cpp

Modified: lldb/trunk/include/lldb/API/SBDebugger.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBDebugger.h?rev=119837&r1=119836&r2=119837&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBDebugger.h (original)
+++ lldb/trunk/include/lldb/API/SBDebugger.h Fri Nov 19 14:47:54 2010
@@ -150,6 +150,12 @@
     DispatchInput (void *baton, const void *data, size_t data_len);
 
     void
+    DispatchInputInterrupt ();
+
+    void
+    DispatchInputEndOfFile ();
+    
+    void
     PushInputReader (lldb::SBInputReader &reader);
 
     const char *
@@ -173,6 +179,9 @@
     void
     SetTerminalWidth (uint32_t term_width);
 
+    lldb::user_id_t
+    GetID ();
+    
     const char *
     GetPrompt() const;
 

Modified: lldb/trunk/include/lldb/Core/Communication.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/Communication.h?rev=119837&r1=119836&r2=119837&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/Communication.h (original)
+++ lldb/trunk/include/lldb/Core/Communication.h Fri Nov 19 14:47:54 2010
@@ -376,7 +376,7 @@
     ///     The number of bytes to append to the cache.
     //------------------------------------------------------------------
     virtual void
-    AppendBytesToCache (const uint8_t *src, size_t src_len, bool broadcast);
+    AppendBytesToCache (const uint8_t *src, size_t src_len, bool broadcast, lldb::ConnectionStatus status);
 
     //------------------------------------------------------------------
     /// Get any available bytes from our data cache. If this call

Modified: lldb/trunk/include/lldb/Core/Debugger.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/Debugger.h?rev=119837&r1=119836&r2=119837&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/Debugger.h (original)
+++ lldb/trunk/include/lldb/Core/Debugger.h Fri Nov 19 14:47:54 2010
@@ -331,6 +331,12 @@
     GetTargetList ();
 
     void
+    DispatchInputInterrupt ();
+
+    void
+    DispatchInputEndOfFile ();
+
+    void
     DispatchInput (const char *bytes, size_t bytes_len);
 
     void

Modified: lldb/trunk/include/lldb/lldb-enumerations.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-enumerations.h?rev=119837&r1=119836&r2=119837&view=diff
==============================================================================
--- lldb/trunk/include/lldb/lldb-enumerations.h (original)
+++ lldb/trunk/include/lldb/lldb-enumerations.h Fri Nov 19 14:47:54 2010
@@ -287,6 +287,7 @@
 typedef enum ConnectionStatus
 {
     eConnectionStatusSuccess,         // Success
+    eConnectionStatusEndOfFile,       // End-of-file encountered
     eConnectionStatusError,           // Check GetError() for details
     eConnectionStatusTimedOut,        // Request timed out
     eConnectionStatusNoConnection,    // No connection
@@ -397,6 +398,8 @@
     eInputReaderReactivate, // reader is on top of the stack again after another reader was popped off 
     eInputReaderDeactivate, // another reader was pushed on the stack 
     eInputReaderGotToken,   // reader got one of its tokens (granularity)
+    eInputReaderInterrupt,  // reader received an interrupt signal (probably from a control-c)
+    eInputReaderEndOfFile,  // reader received an EOF char (probably from a control-d)
     eInputReaderDone        // reader was just popped off the stack and is done
 } InputReaderAction;
 

Modified: lldb/trunk/source/API/SBDebugger.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBDebugger.cpp?rev=119837&r1=119836&r2=119837&view=diff
==============================================================================
--- lldb/trunk/source/API/SBDebugger.cpp (original)
+++ lldb/trunk/source/API/SBDebugger.cpp Fri Nov 19 14:47:54 2010
@@ -659,6 +659,20 @@
 }
 
 void
+SBDebugger::DispatchInputInterrupt ()
+{
+    if (m_opaque_sp)
+        m_opaque_sp->DispatchInputInterrupt ();
+}
+
+void
+SBDebugger::DispatchInputEndOfFile ()
+{
+    if (m_opaque_sp)
+        m_opaque_sp->DispatchInputEndOfFile ();
+}
+
+void
 SBDebugger::PushInputReader (SBInputReader &reader)
 {
     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
@@ -837,3 +851,11 @@
     
     return true;
 }
+
+lldb::user_id_t
+SBDebugger::GetID()
+{
+    if (m_opaque_sp)
+        return m_opaque_sp->GetID();
+    return LLDB_INVALID_UID;
+}

Modified: lldb/trunk/source/Commands/CommandObjectBreakpointCommand.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectBreakpointCommand.cpp?rev=119837&r1=119836&r2=119837&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectBreakpointCommand.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectBreakpointCommand.cpp Fri Nov 19 14:47:54 2010
@@ -468,6 +468,29 @@
         }
         break;
         
+    case eInputReaderInterrupt:
+        {
+            // Finish, and cancel the breakpoint command.
+            reader.SetIsDone (true);
+            BreakpointOptions *bp_options = (BreakpointOptions *) baton;
+            if (bp_options)
+            {
+                Baton *bp_options_baton = bp_options->GetBaton ();
+                if (bp_options_baton)
+                {
+                    ((BreakpointOptions::CommandData *) bp_options_baton->m_data)->user_source.Clear();
+                    ((BreakpointOptions::CommandData *) bp_options_baton->m_data)->script_source.Clear();
+                }
+            }
+            ::fprintf (out_fh, "Warning: No command attached to breakpoint.\n");
+            ::fflush (out_fh);
+        }
+        break;
+        
+    case eInputReaderEndOfFile:
+        reader.SetIsDone (true);
+        break;
+        
     case eInputReaderDone:
         break;
     }

Modified: lldb/trunk/source/Commands/CommandObjectExpression.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectExpression.cpp?rev=119837&r1=119836&r2=119837&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectExpression.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectExpression.cpp Fri Nov 19 14:47:54 2010
@@ -199,7 +199,18 @@
         //    ::fprintf (out_fh, "%3u: ", cmd_object_expr->m_expr_line_count);
         break;
         
+    case eInputReaderInterrupt:
+        cmd_object_expr->m_expr_lines.clear();
+        reader.SetIsDone (true);
+        reader.GetDebugger().GetOutputStream().Printf("%s\n", "Expression evaluation cancelled.");
+        break;
+        
+    case eInputReaderEndOfFile:
+        reader.SetIsDone (true);
+        break;
+        
     case eInputReaderDone:
+		if (cmd_object_expr->m_expr_lines.size() > 0)
         {
             cmd_object_expr->EvaluateExpression (cmd_object_expr->m_expr_lines.c_str(), 
                                                  reader.GetDebugger().GetOutputStream(), 

Modified: lldb/trunk/source/Core/Communication.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Communication.cpp?rev=119837&r1=119836&r2=119837&view=diff
==============================================================================
--- lldb/trunk/source/Core/Communication.cpp (original)
+++ lldb/trunk/source/Core/Communication.cpp Fri Nov 19 14:47:54 2010
@@ -260,12 +260,13 @@
 }
 
 void
-Communication::AppendBytesToCache (const uint8_t * bytes, size_t len, bool broadcast)
+Communication::AppendBytesToCache (const uint8_t * bytes, size_t len, bool broadcast, ConnectionStatus status)
 {
     lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION,
                                  "%p Communication::AppendBytesToCache (src = %p, src_len = %zu, broadcast = %i)",
                                  this, bytes, len, broadcast);
-    if (bytes == NULL || len == 0)
+    if ((bytes == NULL || len == 0)
+        && (status != eConnectionStatusEndOfFile))
         return;
     if (m_callback)
     {
@@ -319,12 +320,16 @@
         {
             size_t bytes_read = comm->ReadFromConnection (buf, sizeof(buf), status, &error);
             if (bytes_read > 0)
-                    comm->AppendBytesToCache (buf, bytes_read, true);
+                comm->AppendBytesToCache (buf, bytes_read, true, status);
+            else if ((bytes_read == 0) 
+                      && status == eConnectionStatusEndOfFile)
+                comm->AppendBytesToCache (buf, bytes_read, true, status);
         }
 
         switch (status)
         {
         case eConnectionStatusSuccess:
+        case eConnectionStatusEndOfFile:
             break;
 
         case eConnectionStatusNoConnection:     // No connection

Modified: lldb/trunk/source/Core/ConnectionFileDescriptor.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ConnectionFileDescriptor.cpp?rev=119837&r1=119836&r2=119837&view=diff
==============================================================================
--- lldb/trunk/source/Core/ConnectionFileDescriptor.cpp (original)
+++ lldb/trunk/source/Core/ConnectionFileDescriptor.cpp Fri Nov 19 14:47:54 2010
@@ -156,8 +156,18 @@
     ssize_t bytes_read = ::read (m_fd, dst, dst_len);
     if (bytes_read == 0)
     {
-        error.SetErrorStringWithFormat("End-of-file.\n");
-        status = eConnectionStatusLostConnection;
+        // 'read' did not return an error, but it didn't return any bytes either ==> End-of-File.
+        //  If the file descriptor is still valid, then we don't return an error; otherwise we do.
+        //  This allows whoever called us to act on the end-of-file, with a valid file descriptor, if they wish.
+        if (fcntl (m_fd, F_GETFL, 0) >= 0)
+        {
+            error.Clear(); // End-of-file, but not an error.  Pass along for the end-of-file handlers.
+        }
+        else
+        {
+            error.SetErrorStringWithFormat("End-of-file.\n");
+        }
+        status = eConnectionStatusEndOfFile;
     }
     else if (bytes_read < 0)
     {

Modified: lldb/trunk/source/Core/Debugger.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Debugger.cpp?rev=119837&r1=119836&r2=119837&view=diff
==============================================================================
--- lldb/trunk/source/Core/Debugger.cpp (original)
+++ lldb/trunk/source/Core/Debugger.cpp Fri Nov 19 14:47:54 2010
@@ -338,20 +338,57 @@
 void
 Debugger::DispatchInputCallback (void *baton, const void *bytes, size_t bytes_len)
 {
-    ((Debugger *)baton)->DispatchInput ((char *)bytes, bytes_len);
-}
+    if (bytes_len > 0)
+        ((Debugger *)baton)->DispatchInput ((char *)bytes, bytes_len);
+    else
+        ((Debugger *)baton)->DispatchInputEndOfFile ();
+}   
 
 
 void
 Debugger::DispatchInput (const char *bytes, size_t bytes_len)
 {
-//    if (bytes == NULL || bytes_len == 0)
-//        return;
+    if (bytes == NULL || bytes_len == 0)
+        return;
 
     WriteToDefaultReader (bytes, bytes_len);
 }
 
 void
+Debugger::DispatchInputInterrupt ()
+{
+    m_input_reader_data.clear();
+    
+    if (!m_input_readers.empty())
+    {
+        while (CheckIfTopInputReaderIsDone ()) ;
+        
+        InputReaderSP reader_sp(m_input_readers.top());
+        if (reader_sp)
+            reader_sp->Notify (eInputReaderInterrupt);
+
+        while (CheckIfTopInputReaderIsDone ()) ;
+    }
+}
+
+void
+Debugger::DispatchInputEndOfFile ()
+{
+    m_input_reader_data.clear();
+    
+    if (!m_input_readers.empty())
+    {
+        while (CheckIfTopInputReaderIsDone ()) ;
+        
+        InputReaderSP reader_sp(m_input_readers.top());
+        if (reader_sp)
+            reader_sp->Notify (eInputReaderEndOfFile);
+
+        while (CheckIfTopInputReaderIsDone ()) ;
+    }
+}
+
+void
 Debugger::WriteToDefaultReader (const char *bytes, size_t bytes_len)
 {
     if (bytes && bytes_len)

Modified: lldb/trunk/source/Core/InputReader.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/InputReader.cpp?rev=119837&r1=119836&r2=119837&view=diff
==============================================================================
--- lldb/trunk/source/Core/InputReader.cpp (original)
+++ lldb/trunk/source/Core/InputReader.cpp Fri Nov 19 14:47:54 2010
@@ -324,6 +324,10 @@
         m_active = false;
         break;
     
+    case eInputReaderInterrupt:
+    case eInputReaderEndOfFile:
+        break;
+    
     case eInputReaderGotToken:
         return; // We don't notify the tokens here, it is done in HandleRawBytes
     }

Modified: lldb/trunk/source/Interpreter/CommandInterpreter.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/CommandInterpreter.cpp?rev=119837&r1=119836&r2=119837&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/CommandInterpreter.cpp (original)
+++ lldb/trunk/source/Interpreter/CommandInterpreter.cpp Fri Nov 19 14:47:54 2010
@@ -860,6 +860,12 @@
         }
         break;
         
+    case eInputReaderInterrupt:
+    case eInputReaderEndOfFile:
+        *response_ptr = false;  // Assume ^C or ^D means cancel the proposed action
+        reader.SetIsDone (true);
+        break;
+        
     case eInputReaderDone:
         break;
     }

Modified: lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp?rev=119837&r1=119836&r2=119837&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp (original)
+++ lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp Fri Nov 19 14:47:54 2010
@@ -272,11 +272,6 @@
         PyRun_SimpleString (run_string.GetData());
         PyRun_SimpleString ("sys.stdin = new_stdin");
 
-        PyRun_SimpleString ("new_mode = tcgetattr(new_stdin)");
-        PyRun_SimpleString ("new_mode[3] = new_mode[3] | ECHO | ICANON");
-        PyRun_SimpleString ("new_mode[6][VEOF] = 255");
-        PyRun_SimpleString ("tcsetattr (new_stdin, TCSANOW, new_mode)");
-
         run_string.Clear();
         run_string.Printf ("lldb.debugger_unique_id = %d", interpreter.GetDebugger().GetID());
         PyRun_SimpleString (run_string.GetData());
@@ -302,26 +297,10 @@
     {
         int success;
 
-
-        // Save the current input file handle state before executing the command.
-        int input_fd;
-        struct termios tmp_termios;
-        bool valid_termios = false;
-        FILE *input_fh = m_interpreter.GetDebugger().GetInputFileHandle();
-        if (input_fh != NULL)
-        {
-            input_fd = ::fileno (input_fh);
-            valid_termios = ::tcgetattr (input_fd, &tmp_termios) == 0;
-        }
-
         success = PyRun_SimpleString (command);
         if (success == 0)
             return true;
 
-        // Restore the input file handle state after executing the command.
-        if (valid_termios)
-            ::tcsetattr (input_fd, TCSANOW, &tmp_termios);
-
         // The one-liner failed.  Append the error message.
         if (result)
             result->AppendErrorWithFormat ("python failed attempting to evaluate '%s'\n", command);
@@ -366,12 +345,6 @@
 
             script_interpreter->m_termios_valid = ::tcgetattr (input_fd, &script_interpreter->m_termios) == 0;
             
-            if (script_interpreter->m_termios_valid)
-            {
-                struct termios tmp_termios = script_interpreter->m_termios;
-                tmp_termios.c_cc[VEOF] = _POSIX_VDISABLE;
-                ::tcsetattr (input_fd, TCSANOW, &tmp_termios);
-            }
             char error_str[1024];
             if (script_interpreter->m_embedded_python_pty.OpenFirstAvailableMaster (O_RDWR|O_NOCTTY, error_str, 
                                                                                     sizeof(error_str)))
@@ -411,6 +384,14 @@
 
     case eInputReaderReactivate:
         break;
+        
+    case eInputReaderInterrupt:
+        ::write (script_interpreter->m_embedded_python_pty.GetMasterFileDescriptor(), "raise KeyboardInterrupt\n", 24);
+        break;
+        
+    case eInputReaderEndOfFile:
+        ::write (script_interpreter->m_embedded_python_pty.GetMasterFileDescriptor(), "quit()\n", 7);
+        break;
 
     case eInputReaderGotToken:
         if (script_interpreter->m_embedded_python_pty.GetMasterFileDescriptor() != -1)
@@ -724,6 +705,17 @@
         }
         break;
 
+    case eInputReaderEndOfFile:
+    case eInputReaderInterrupt:
+        // Control-c (SIGINT) & control-d both mean finish & exit.
+        reader.SetIsDone(true);
+        
+        // Control-c (SIGINT) ALSO means cancel; do NOT create a breakpoint command.
+        if (notification == eInputReaderInterrupt)
+            commands_in_progress.Clear();  
+        
+        // Fall through here...
+
     case eInputReaderDone:
         {
             BreakpointOptions *bp_options = (BreakpointOptions *)baton;
@@ -843,6 +835,10 @@
     int num_lines = user_input.GetSize ();
     StreamString sstr;
 
+    // Check to see if we have any data; if not, just return.
+    if (user_input.GetSize() == 0)
+        return false;
+
     // Take what the user wrote, wrap it all up inside one big auto-generated Python function, passing in the
     // frame and breakpoint location as parameters to the function.
 
@@ -933,10 +929,6 @@
         PyRun_SimpleString ("save_stdin = sys.stdin");
         run_string.Printf ("sys.stdin = open ('%s', 'r')", pty_slave_name);
         PyRun_SimpleString (run_string.GetData());
-        PyRun_SimpleString ("new_mode = tcgetattr(sys.stdin)");
-        PyRun_SimpleString ("new_mode[3] = new_mode[3] | ECHO | ICANON");
-        PyRun_SimpleString ("new_mode[6][VEOF] = 255");
-        PyRun_SimpleString ("tcsetattr (sys.stdin, TCSANOW, new_mode)");
         
 	    // The following call drops into the embedded interpreter loop and stays there until the
 	    // user chooses to exit from the Python interpreter.

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=119837&r1=119836&r2=119837&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp Fri Nov 19 14:47:54 2010
@@ -551,7 +551,8 @@
 }
 
 void
-GDBRemoteCommunication::AppendBytesToCache (const uint8_t *src, size_t src_len, bool broadcast)
+GDBRemoteCommunication::AppendBytesToCache (const uint8_t *src, size_t src_len, bool broadcast, 
+                                            ConnectionStatus status)
 {
     // Put the packet data into the buffer in a thread safe fashion
     Mutex::Locker locker(m_bytes_mutex);

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h?rev=119837&r1=119836&r2=119837&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h Fri Nov 19 14:47:54 2010
@@ -110,7 +110,7 @@
     // Communication overrides
     //------------------------------------------------------------------
     virtual void
-    AppendBytesToCache (const uint8_t *src, size_t src_len, bool broadcast);
+    AppendBytesToCache (const uint8_t *src, size_t src_len, bool broadcast, lldb::ConnectionStatus status);
 
 
     lldb::pid_t

Modified: lldb/trunk/source/Target/Process.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Process.cpp?rev=119837&r1=119836&r2=119837&view=diff
==============================================================================
--- lldb/trunk/source/Target/Process.cpp (original)
+++ lldb/trunk/source/Target/Process.cpp Fri Nov 19 14:47:54 2010
@@ -1478,10 +1478,6 @@
                 }
                 else
                 {
-                    // Since we are eating the event, we need to update our state
-                    // otherwise the process state will not match reality...
-                    SetPublicState(state);
-
                     if (StateIsStoppedState (state))
                     {
                         // We caused the process to interrupt itself, so mark this
@@ -1508,7 +1504,7 @@
         // stopped the process, intercepted the event and set the interrupted
         // bool in the event.
         if (event_sp)
-            BroadcastEvent(event_sp);
+            m_private_state_broadcaster.BroadcastEvent(event_sp);
 
     }
     return error;
@@ -2175,6 +2171,14 @@
         }
         break;
         
+    case eInputReaderInterrupt:
+        process->Halt ();
+        break;
+            
+    case eInputReaderEndOfFile:
+        process->AppendSTDOUT ("^D", 2);
+        break;
+        
     case eInputReaderDone:
         break;
         

Modified: lldb/trunk/tools/driver/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/driver/Driver.cpp?rev=119837&r1=119836&r2=119837&view=diff
==============================================================================
--- lldb/trunk/tools/driver/Driver.cpp (original)
+++ lldb/trunk/tools/driver/Driver.cpp Fri Nov 19 14:47:54 2010
@@ -40,6 +40,7 @@
 static struct termios g_old_stdin_termios;
 
 static char *g_debugger_name =  (char *) "";
+static Driver *g_driver = NULL;
 
 // In the Driver::MainLoop, we change the terminal settings.  This function is
 // added as an atexit handler to make sure we clean them up.
@@ -98,10 +99,13 @@
     g_debugger_name = (char *) m_debugger.GetInstanceName();
     if (g_debugger_name == NULL)
         g_debugger_name = (char *) "";
+    g_driver = this;
 }
 
 Driver::~Driver ()
 {
+    g_driver = NULL;
+    g_debugger_name = NULL;
 }
 
 void
@@ -1091,6 +1095,23 @@
     case eInputReaderDeactivate:
         break;
 
+    case eInputReaderInterrupt:
+        if (driver->m_io_channel_ap.get() != NULL)
+        {
+            driver->m_io_channel_ap->OutWrite ("^C\n", 3);
+            driver->m_io_channel_ap->RefreshPrompt();
+        }
+        break;
+        
+    case eInputReaderEndOfFile:
+        if (driver->m_io_channel_ap.get() != NULL)
+        {
+            driver->m_io_channel_ap->OutWrite ("^D\n", 3);
+            driver->m_io_channel_ap->RefreshPrompt ();
+        }
+        write (driver->m_editline_pty.GetMasterFileDescriptor(), "quit\n", 5);
+        break;
+
     case eInputReaderGotToken:
         write (driver->m_editline_pty.GetMasterFileDescriptor(), bytes, bytes_len);
         break;
@@ -1370,6 +1391,24 @@
     }
 }
 
+void
+sigint_handler (int signo)
+{
+	static bool g_interrupt_sent = false;
+    if (g_driver)
+	{
+		if (!g_interrupt_sent)
+		{
+			g_interrupt_sent = true;
+        	g_driver->GetDebugger().DispatchInputInterrupt();
+			g_interrupt_sent = false;
+			return;
+		}
+	}
+    
+	exit (signo);
+}
+
 int
 main (int argc, char const *argv[])
 {
@@ -1379,6 +1418,7 @@
 
     signal (SIGPIPE, SIG_IGN);
     signal (SIGWINCH, sigwinch_handler);
+    signal (SIGINT, sigint_handler);
 
     // Create a scope for driver so that the driver object will destroy itself
     // before SBDebugger::Terminate() is called.

Modified: lldb/trunk/tools/driver/IOChannel.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/driver/IOChannel.cpp?rev=119837&r1=119836&r2=119837&view=diff
==============================================================================
--- lldb/trunk/tools/driver/IOChannel.cpp (original)
+++ lldb/trunk/tools/driver/IOChannel.cpp Fri Nov 19 14:47:54 2010
@@ -448,12 +448,12 @@
     if (! IsGettingCommand())
         return;
 
-    // Compare the current time versus the last time el_gets was called.  If less than
-    // 10000 microseconds (10000000 nanoseconds) have elapsed, wait 10000 microseconds, to ensure el_gets had time
-    // to finish writing the prompt before we start writing here.
+    // Compare the current time versus the last time el_gets was called.  If less than 40 milliseconds
+    // (40,0000 microseconds or 40,000,0000 nanoseconds) have elapsed, wait 40,0000 microseconds, to ensure el_gets had
+    // time to finish writing the prompt before we start writing here.
 
-    if (ElapsedNanoSecondsSinceEnteringElGets() < 10000000)
-        usleep (10000);
+    if (ElapsedNanoSecondsSinceEnteringElGets() < (40 * 1000 * 1000))
+        usleep (40 * 1000);
 
     // Use the mutex to make sure OutWrite, ErrWrite and Refresh prompt do not interfere with
     // each other's output.





More information about the lldb-commits mailing list