2010-06-09 00:52:24 +08:00
|
|
|
//===-- Driver.h ------------------------------------------------*- C++ -*-===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#ifndef lldb_Driver_h_
|
|
|
|
#define lldb_Driver_h_
|
|
|
|
|
2010-06-10 05:28:42 +08:00
|
|
|
#include "lldb/Utility/PseudoTerminal.h"
|
2010-06-09 00:52:24 +08:00
|
|
|
|
|
|
|
#include <set>
|
|
|
|
#include <bitset>
|
|
|
|
#include <string>
|
|
|
|
#include <vector>
|
|
|
|
|
2010-06-09 14:50:29 +08:00
|
|
|
#include "lldb/API/SBDefines.h"
|
|
|
|
#include "lldb/API/SBBroadcaster.h"
|
2010-06-23 09:19:29 +08:00
|
|
|
#include "lldb/API/SBDebugger.h"
|
2010-06-09 14:50:29 +08:00
|
|
|
#include "lldb/API/SBError.h"
|
|
|
|
#include "lldb/API/SBInputReader.h"
|
2010-06-09 00:52:24 +08:00
|
|
|
|
This patch captures and serializes all output being written by the
command line driver, including the lldb prompt being output by
editline, the asynchronous process output & error messages, and
asynchronous messages written by target stop-hooks.
As part of this it introduces a new Stream class,
StreamAsynchronousIO. A StreamAsynchronousIO object is created with a
broadcaster, who will eventually broadcast the stream's data for a
listener to handle, and an event type indicating what type of event
the broadcaster will broadcast. When the Write method is called on a
StreamAsynchronousIO object, the data is appended to an internal
string. When the Flush method is called on a StreamAsynchronousIO
object, it broadcasts it's data string and clears the string.
Anything in lldb-core that needs to generate asynchronous output for
the end-user should use the StreamAsynchronousIO objects.
I have also added a new notification type for InputReaders, to let
them know that a asynchronous output has been written. This is to
allow the input readers to, for example, refresh their prompts and
lines, if desired. I added the case statements to all the input
readers to catch this notification, but I haven't added any code for
handling them yet (except to the IOChannel input reader).
llvm-svn: 130721
2011-05-03 04:41:46 +08:00
|
|
|
#define ASYNC true
|
|
|
|
#define NO_ASYNC false
|
2010-06-09 00:52:24 +08:00
|
|
|
|
|
|
|
class IOChannel;
|
|
|
|
|
|
|
|
namespace lldb
|
|
|
|
{
|
|
|
|
class SBInputReader;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
class Driver : public lldb::SBBroadcaster
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
enum {
|
|
|
|
eBroadcastBitReadyForInput = (1 << 0),
|
|
|
|
eBroadcastBitThreadShouldExit = (1 << 1)
|
|
|
|
};
|
|
|
|
|
|
|
|
Driver ();
|
|
|
|
|
|
|
|
virtual
|
|
|
|
~Driver ();
|
|
|
|
|
|
|
|
void
|
|
|
|
MainLoop ();
|
|
|
|
|
|
|
|
void
|
|
|
|
PutSTDIN (const char *src, size_t src_len);
|
|
|
|
|
|
|
|
void
|
|
|
|
GetFromMaster (const char *src, size_t src_len);
|
|
|
|
|
|
|
|
bool
|
|
|
|
HandleIOEvent (const lldb::SBEvent &event);
|
|
|
|
|
|
|
|
void
|
|
|
|
HandleProcessEvent (const lldb::SBEvent &event);
|
|
|
|
|
2012-02-08 13:23:15 +08:00
|
|
|
void
|
|
|
|
HandleBreakpointEvent (const lldb::SBEvent &event);
|
|
|
|
|
2012-10-11 02:32:14 +08:00
|
|
|
void
|
|
|
|
HandleThreadEvent (const lldb::SBEvent &event);
|
|
|
|
|
2010-06-23 09:19:29 +08:00
|
|
|
lldb::SBError
|
|
|
|
ParseArgs (int argc, const char *argv[], FILE *out_fh, bool &do_exit);
|
2010-06-09 00:52:24 +08:00
|
|
|
|
|
|
|
const char *
|
|
|
|
GetFilename() const;
|
|
|
|
|
|
|
|
const char *
|
|
|
|
GetCrashLogFilename() const;
|
|
|
|
|
|
|
|
const char *
|
|
|
|
GetArchName() const;
|
|
|
|
|
|
|
|
lldb::ScriptLanguage
|
|
|
|
GetScriptLanguage() const;
|
|
|
|
|
2013-09-14 08:20:24 +08:00
|
|
|
void
|
|
|
|
ExecuteInitialCommands (bool before_file);
|
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
bool
|
|
|
|
GetDebugMode() const;
|
|
|
|
|
|
|
|
|
|
|
|
class OptionData
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
OptionData ();
|
|
|
|
~OptionData ();
|
|
|
|
|
|
|
|
void
|
|
|
|
Clear();
|
|
|
|
|
2013-09-14 08:20:24 +08:00
|
|
|
void
|
|
|
|
AddInitialCommand (const char *command, bool before_file, bool is_file, lldb::SBError &error);
|
|
|
|
|
2011-03-25 05:19:54 +08:00
|
|
|
//static OptionDefinition m_cmd_option_table[];
|
2010-06-09 00:52:24 +08:00
|
|
|
|
2010-12-09 06:23:24 +08:00
|
|
|
std::vector<std::string> m_args;
|
2010-06-09 00:52:24 +08:00
|
|
|
lldb::ScriptLanguage m_script_lang;
|
2012-08-16 06:10:42 +08:00
|
|
|
std::string m_core_file;
|
2010-06-09 00:52:24 +08:00
|
|
|
std::string m_crash_log;
|
2013-09-14 08:20:24 +08:00
|
|
|
std::vector<std::pair<bool,std::string> > m_initial_commands;
|
|
|
|
std::vector<std::pair<bool,std::string> > m_after_file_commands;
|
2010-06-09 00:52:24 +08:00
|
|
|
bool m_debug_mode;
|
2013-09-14 08:20:24 +08:00
|
|
|
bool m_source_quietly;
|
2010-06-09 00:52:24 +08:00
|
|
|
bool m_print_version;
|
2012-12-22 06:22:26 +08:00
|
|
|
bool m_print_python_path;
|
2010-06-09 00:52:24 +08:00
|
|
|
bool m_print_help;
|
2011-09-14 07:25:31 +08:00
|
|
|
bool m_wait_for;
|
|
|
|
std::string m_process_name;
|
|
|
|
lldb::pid_t m_process_pid;
|
2010-08-31 03:44:40 +08:00
|
|
|
bool m_use_external_editor; // FIXME: When we have set/show variables we can remove this from here.
|
2010-06-09 00:52:24 +08:00
|
|
|
typedef std::set<char> OptionSet;
|
|
|
|
OptionSet m_seen_options;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
static lldb::SBError
|
|
|
|
SetOptionValue (int option_idx,
|
|
|
|
const char *option_arg,
|
|
|
|
Driver::OptionData &data);
|
|
|
|
|
|
|
|
|
2010-06-23 09:19:29 +08:00
|
|
|
lldb::SBDebugger &
|
|
|
|
GetDebugger()
|
|
|
|
{
|
|
|
|
return m_debugger;
|
|
|
|
}
|
2011-05-10 07:06:58 +08:00
|
|
|
|
|
|
|
bool
|
|
|
|
EditlineReaderIsTop ()
|
|
|
|
{
|
|
|
|
return m_debugger.InputReaderIsTopReader (m_editline_reader);
|
|
|
|
}
|
2010-06-23 09:19:29 +08:00
|
|
|
|
2012-02-29 12:21:24 +08:00
|
|
|
bool
|
|
|
|
GetIsDone () const
|
|
|
|
{
|
|
|
|
return m_done;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
SetIsDone ()
|
|
|
|
{
|
|
|
|
m_done = true;
|
|
|
|
}
|
2013-02-23 06:56:55 +08:00
|
|
|
|
|
|
|
void
|
|
|
|
ResizeWindow (unsigned short col);
|
2012-02-29 12:21:24 +08:00
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
private:
|
2010-06-23 09:19:29 +08:00
|
|
|
lldb::SBDebugger m_debugger;
|
2010-06-09 00:52:24 +08:00
|
|
|
lldb_utility::PseudoTerminal m_editline_pty;
|
|
|
|
FILE *m_editline_slave_fh;
|
|
|
|
lldb::SBInputReader m_editline_reader;
|
2013-04-19 06:45:39 +08:00
|
|
|
std::unique_ptr<IOChannel> m_io_channel_ap;
|
2010-06-09 00:52:24 +08:00
|
|
|
OptionData m_option_data;
|
<rdar://problem/13764135>
The "lldb" driver was interfering with STDOUT and STDERR if the output was over 1024 charcters long. The output was grabbing 1024 characters at a time, before it output the characters, it was writing characters to the screen to clear the current line. This has been fixed.
I also fixed the command interpreter from mixing the "(lldb) " prompt in with program output by always manually checking for program output. This was done by having the command interpreter know when it is in the middle of executing a command by setting a bool. This was needed since sometimes when a command would run the target, like with a command like 'expression (int)printf("hello\n")', the process would push a new input reader, and then pop it when it was done. This popping of the input reader would cause the command interpreter to get sent a reactivated message (from the private process state thread) and cause it to ask for another command, even though we were still in the middle of the command ('expression (int)printf("hello\n")'). Now we set a bool to true, run the command and set the bool to false. If we get reactivated while we are in the middle of a command, we don't say we are ready for a new command. This coupled with emitting the STDOUT/STDERR first after each command, followed by the command results, followed by then saying we are ready for a new command, should help cleanup the command line output on all platforms.
llvm-svn: 181807
2013-05-15 01:36:51 +08:00
|
|
|
bool m_executing_user_command;
|
2010-06-09 00:52:24 +08:00
|
|
|
bool m_waiting_for_command;
|
2012-02-29 12:21:24 +08:00
|
|
|
bool m_done;
|
2010-06-09 00:52:24 +08:00
|
|
|
|
|
|
|
void
|
|
|
|
ResetOptionValues ();
|
|
|
|
|
2010-09-30 02:35:42 +08:00
|
|
|
size_t
|
2010-06-09 00:52:24 +08:00
|
|
|
GetProcessSTDOUT ();
|
|
|
|
|
2010-09-30 02:35:42 +08:00
|
|
|
size_t
|
2010-06-09 00:52:24 +08:00
|
|
|
GetProcessSTDERR ();
|
|
|
|
|
|
|
|
void
|
2010-08-27 05:32:51 +08:00
|
|
|
UpdateSelectedThread ();
|
2010-06-09 00:52:24 +08:00
|
|
|
|
|
|
|
void
|
|
|
|
CloseIOChannelFile ();
|
|
|
|
|
|
|
|
static size_t
|
|
|
|
EditLineInputReaderCallback (void *baton,
|
|
|
|
lldb::SBInputReader *reader,
|
|
|
|
lldb::InputReaderAction notification,
|
|
|
|
const char *bytes,
|
|
|
|
size_t bytes_len);
|
|
|
|
|
|
|
|
static void
|
|
|
|
ReadThreadBytesReceived (void *baton, const void *src, size_t src_len);
|
|
|
|
|
|
|
|
static void
|
|
|
|
MasterThreadBytesReceived (void *baton, const void *src, size_t src_len);
|
|
|
|
|
|
|
|
void
|
|
|
|
ReadyForCommand ();
|
|
|
|
};
|
|
|
|
|
2010-06-09 17:50:17 +08:00
|
|
|
#endif // lldb_Driver_h_
|