Skip to content

Commit

Permalink
Improve LLDB prompt handling
Browse files Browse the repository at this point in the history
Summary:
There is an issue in lldb where the command prompt can appear at the wrong time. The partial fix
we have in for this is not working all the time and is introducing unnecessary delays. This
change does:
- Change Process:SyncIOHandler to use integer start id's for synchronization to avoid it being
  confused by quick start-stop cycles. I picked this up from a suggested patch by Greg to
  lldb-dev.
- coordinates printing of asynchronous text with the iohandlers. This is also based on a
  (different) Greg's patch, but I have added stronger synchronization to it to avoid races.

Together, these changes solve the prompt problem for me on linux (both with and without libedit).
I think they should behave similarly on Mac and FreeBSD and I think they will not make matters
worse for windows.

Test Plan: Prompt comes out alright. All tests still pass on linux.

Reviewers: clayborg, emaste, zturner

Subscribers: lldb-commits

Differential Revision: http://reviews.llvm.org/D9823

llvm-svn: 238313
  • Loading branch information
labath committed May 27, 2015
1 parent bed77de commit 4446487
Show file tree
Hide file tree
Showing 13 changed files with 312 additions and 402 deletions.
9 changes: 3 additions & 6 deletions lldb/include/lldb/Core/Debugger.h
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,9 @@ friend class SourceManager; // For GetSourceFileCache.
bool
IsTopIOHandler (const lldb::IOHandlerSP& reader_sp);

void
PrintAsync (const char *s, size_t len, bool is_stdout);

ConstString
GetTopIOHandlerControlSequence(char ch);

Expand All @@ -219,12 +222,6 @@ friend class SourceManager; // For GetSourceFileCache.
const char *
GetIOHandlerHelpPrologue();

bool
HideTopIOHandler();

void
RefreshTopIOHandler();

static lldb::DebuggerSP
FindDebuggerWithID (lldb::user_id_t id);

Expand Down
145 changes: 62 additions & 83 deletions lldb/include/lldb/Core/IOHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,18 +67,6 @@ namespace lldb_private {
virtual void
Run () = 0;

// Hide any characters that have been displayed so far so async
// output can be displayed. Refresh() will be called after the
// output has been displayed.
virtual void
Hide () = 0;

// Called when the async output has been received in order to update
// the input reader (refresh the prompt and redisplay any current
// line(s) that are being edited
virtual void
Refresh () = 0;

// Called when an input reader should relinquish its control so another
// can be pushed onto the IO handler stack, or so the current IO
// handler can pop itself off the stack
Expand Down Expand Up @@ -246,7 +234,14 @@ namespace lldb_private {

void
WaitForPop ();


virtual void
PrintAsync (Stream *stream, const char *s, size_t len)
{
stream->Write (s, len);
stream->Flush();
}

protected:
Debugger &m_debugger;
lldb::StreamFileSP m_input_sp;
Expand Down Expand Up @@ -448,17 +443,17 @@ namespace lldb_private {
{
}

virtual ConstString
IOHandlerGetControlSequence (char ch)
ConstString
IOHandlerGetControlSequence (char ch) override
{
if (ch == 'd')
return ConstString (m_end_line + "\n");
return ConstString();
}

virtual bool
bool
IOHandlerIsInputComplete (IOHandler &io_handler,
StringList &lines)
StringList &lines) override
{
// Determine whether the end of input signal has been entered
const size_t num_lines = lines.GetSize();
Expand Down Expand Up @@ -507,53 +502,47 @@ namespace lldb_private {
virtual
~IOHandlerEditline ();

virtual void
Run ();
void
Run () override;

virtual void
Hide ();

virtual void
Refresh ();

virtual void
Cancel ();
void
Cancel () override;

virtual bool
Interrupt ();
bool
Interrupt () override;

virtual void
GotEOF();
void
GotEOF() override;

virtual void
Activate ();
void
Activate () override;

virtual void
Deactivate ();
void
Deactivate () override;

virtual ConstString
GetControlSequence (char ch)
ConstString
GetControlSequence (char ch) override
{
return m_delegate.IOHandlerGetControlSequence (ch);
}

virtual const char *
GetCommandPrefix ()
const char *
GetCommandPrefix () override
{
return m_delegate.IOHandlerGetCommandPrefix ();
}

virtual const char *
GetHelpPrologue ()
const char *
GetHelpPrologue () override
{
return m_delegate.IOHandlerGetHelpPrologue ();
}

virtual const char *
GetPrompt ();
const char *
GetPrompt () override;

virtual bool
SetPrompt (const char *prompt);
bool
SetPrompt (const char *prompt) override;

const char *
GetContinuationPrompt ();
Expand Down Expand Up @@ -591,6 +580,9 @@ namespace lldb_private {
uint32_t
GetCurrentLineIndex () const;

void
PrintAsync (Stream *stream, const char *s, size_t len) override;

private:
#ifndef LLDB_DISABLE_LIBEDIT
static bool
Expand Down Expand Up @@ -649,17 +641,17 @@ namespace lldb_private {
return m_user_response;
}

virtual int
int
IOHandlerComplete (IOHandler &io_handler,
const char *current_line,
const char *cursor,
const char *last_char,
int skip_first_n_matches,
int max_matches,
StringList &matches);
StringList &matches) override;

virtual void
IOHandlerInputComplete (IOHandler &io_handler, std::string &data);
void
IOHandlerInputComplete (IOHandler &io_handler, std::string &data) override;

protected:
const bool m_default_response;
Expand All @@ -672,32 +664,25 @@ namespace lldb_private {
public:
IOHandlerCursesGUI (Debugger &debugger);

virtual
~IOHandlerCursesGUI ();

virtual void
Run ();
~IOHandlerCursesGUI () override;

virtual void
Hide ();
void
Run () override;

virtual void
Refresh ();

virtual void
Cancel ();
void
Cancel () override;

virtual bool
Interrupt ();
bool
Interrupt () override;

virtual void
GotEOF();
void
GotEOF() override;

virtual void
Activate ();
void
Activate () override;

virtual void
Deactivate ();
void
Deactivate () override;

protected:
curses::ApplicationAP m_app_ap;
Expand All @@ -712,20 +697,11 @@ namespace lldb_private {
virtual
~IOHandlerCursesValueObjectList ();

virtual void
Run ();

virtual void
Hide ();

virtual void
Refresh ();

virtual bool
HandleInterrupt ();
void
Run () override;

virtual void
GotEOF();
void
GotEOF() override;
protected:
ValueObjectList m_valobj_list;
};
Expand Down Expand Up @@ -850,7 +826,10 @@ namespace lldb_private {
return NULL;
}

protected:
void
PrintAsync (Stream *stream, const char *s, size_t len);

protected:

typedef std::vector<lldb::IOHandlerSP> collection;
collection m_stack;
Expand Down
8 changes: 4 additions & 4 deletions lldb/include/lldb/Core/StreamAsynchronousIO.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class StreamAsynchronousIO :
public Stream
{
public:
StreamAsynchronousIO (Broadcaster &broadcaster, uint32_t broadcast_event_type);
StreamAsynchronousIO (Debugger &debugger, bool for_stdout);

virtual ~StreamAsynchronousIO ();

Expand All @@ -32,9 +32,9 @@ class StreamAsynchronousIO :


private:
Broadcaster &m_broadcaster;
uint32_t m_broadcast_event_type;
std::string m_accumulated_data;
Debugger &m_debugger;
std::string m_data;
bool m_for_stdout;
};

} // namespace lldb_private
Expand Down
18 changes: 9 additions & 9 deletions lldb/include/lldb/Host/Editline.h
Original file line number Diff line number Diff line change
Expand Up @@ -171,17 +171,13 @@ namespace lldb_private {
uint32_t
GetCurrentLine();

/// Hides the current input session in preparation for output
void
Hide();

/// Prepare to return to editing after a call to Hide()
void
Refresh();

/// Interrupt the current edit as if ^C was pressed
bool
Interrupt();

/// Cancel this edit and oblitarate all trace of it
bool
Cancel();

/// Register a callback for the tab key
void
Expand All @@ -207,6 +203,9 @@ namespace lldb_private {
bool
GetLines (int first_line_number, StringList &lines, bool &interrupted);

void
PrintAsync (Stream *stream, const char *s, size_t len);

private:

/// Sets the lowest line number for multi-line editing sessions. A value of zero suppresses
Expand Down Expand Up @@ -335,7 +334,6 @@ namespace lldb_private {
bool m_multiline_enabled = false;
std::vector<EditLineStringType> m_input_lines;
EditorStatus m_editor_status;
bool m_editor_getting_char = false;
bool m_color_prompts = true;
int m_terminal_width = 0;
int m_base_line_number = 0;
Expand All @@ -359,6 +357,8 @@ namespace lldb_private {
const char * m_fix_indentation_callback_chars = nullptr;
CompleteCallbackType m_completion_callback = nullptr;
void * m_completion_callback_baton = nullptr;

Mutex m_output_mutex;
};
}

Expand Down
16 changes: 8 additions & 8 deletions lldb/include/lldb/Target/Process.h
Original file line number Diff line number Diff line change
Expand Up @@ -2746,6 +2746,11 @@ class Process :
Listener *hijack_listener = NULL,
Stream *stream = NULL);

uint32_t
GetIOHandlerID () const
{
return m_iohandler_sync.GetValue();
}

//--------------------------------------------------------------------------------------
/// Waits for the process state to be running within a given msec timeout.
Expand All @@ -2756,14 +2761,9 @@ class Process :
/// @param[in] timeout_msec
/// The maximum time length to wait for the process to transition to the
/// eStateRunning state, specified in milliseconds.
///
/// @return
/// true if successfully signalled that process started and IOHandler pushes, false
/// if it timed out.
//--------------------------------------------------------------------------------------
bool
SyncIOHandler (uint64_t timeout_msec);

void
SyncIOHandler (uint32_t iohandler_id, uint64_t timeout_msec);

lldb::StateType
WaitForStateChangedEvents (const TimeValue *timeout,
Expand Down Expand Up @@ -3186,7 +3186,7 @@ class Process :
std::string m_stderr_data;
Mutex m_profile_data_comm_mutex;
std::vector<std::string> m_profile_data;
Predicate<bool> m_iohandler_sync;
Predicate<uint32_t> m_iohandler_sync;
MemoryCache m_memory_cache;
AllocatedMemoryCache m_allocated_memory_cache;
bool m_should_detach; /// Should we detach if the process object goes away with an explicit call to Kill or Detach?
Expand Down
Loading

0 comments on commit 4446487

Please sign in to comment.