Skip to content

Commit

Permalink
Fixed CTRL+C related issues:
Browse files Browse the repository at this point in the history
- 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>

llvm-svn: 207816
  • Loading branch information
Greg Clayton committed May 2, 2014
1 parent 34a38d8 commit f0066ad
Showing 15 changed files with 235 additions and 83 deletions.
9 changes: 6 additions & 3 deletions lldb/include/lldb/Core/ConnectionFileDescriptor.h
Original file line number Diff line number Diff line change
@@ -77,6 +77,12 @@ class ConnectionFileDescriptor :
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 @@ class ConnectionFileDescriptor :

void
CloseCommandPipe ();

lldb::ConnectionStatus
BytesAvailable (uint32_t timeout_usec, Error *error_ptr);

lldb::ConnectionStatus
SocketListen (const char *host_and_port, Error *error_ptr);
31 changes: 21 additions & 10 deletions lldb/include/lldb/Core/IOHandler.h
Original file line number Diff line number Diff line change
@@ -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();
11 changes: 8 additions & 3 deletions lldb/include/lldb/Host/Editline.h
Original file line number Diff line number Diff line change
@@ -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 @@ class Editline
~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 @@ class Editline
void
Refresh();

void
bool
Interrupt ();

void
@@ -203,6 +207,7 @@ class Editline
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
5 changes: 4 additions & 1 deletion lldb/include/lldb/Interpreter/CommandInterpreter.h
Original file line number Diff line number Diff line change
@@ -479,12 +479,15 @@ class CommandInterpreter :
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 ();
17 changes: 16 additions & 1 deletion lldb/include/lldb/Interpreter/ScriptInterpreterPython.h
Original file line number Diff line number Diff line change
@@ -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 @@ class ScriptInterpreterPython :
}


PyThreadState *
GetThreadState()
{
return m_command_thread_state;
}

void
SetThreadState (PyThreadState *s)
{
if (s)
m_command_thread_state = s;
}

//----------------------------------------------------------------------
// IOHandlerDelegate
//----------------------------------------------------------------------
@@ -399,7 +414,7 @@ class ScriptInterpreterPython :
// FILE* m_tmp_fh;
PyGILState_STATE m_GILState;
};
private:
protected:

enum ActiveIOHandler {
eIOHandlerNone,
3 changes: 2 additions & 1 deletion lldb/include/lldb/lldb-enumerations.h
Original file line number Diff line number Diff line change
@@ -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
3 changes: 3 additions & 0 deletions lldb/source/Core/Communication.cpp
Original file line number Diff line number Diff line change
@@ -382,6 +382,8 @@ Communication::ReadThread (lldb::thread_arg_t p)
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 (lldb::ConnectionStatus status)
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];
31 changes: 22 additions & 9 deletions lldb/source/Core/ConnectionFileDescriptor.cpp
Original file line number Diff line number Diff line change
@@ -361,6 +361,14 @@ ConnectionFileDescriptor::Connect (const char *s, Error *error_ptr)
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 (Error *error_ptr)
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 (uint32_t timeout_usec, Error *error_pt
{
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;
}
}
}
}
Loading

0 comments on commit f0066ad

Please sign in to comment.