Rework the way we pass "run multiple command" options to the various API's that

do that (RunCommandInterpreter, HandleCommands, HandleCommandsFromFile) to gather
the options into an options class.  Also expose that to the SB API's.

Change the way the "-o" options to the lldb driver are processed so:
1) They are run synchronously - didn't really make any sense to run the asynchronously.
2) The stop on error
3) "quit" in one of the -o commands will not quit lldb - not the command interpreter
that was running the -o commands.

I added an entry to the run options to stop-on-crash, but I haven't implemented that yet.

llvm-svn: 219553
This commit is contained in:
Jim Ingham 2014-10-11 00:38:27 +00:00
parent 41c79d934b
commit 26c7bf9312
17 changed files with 563 additions and 121 deletions

View File

@ -15,6 +15,59 @@
namespace lldb {
class SBCommandInterpreterRunOptions
{
friend class SBDebugger;
public:
SBCommandInterpreterRunOptions();
~SBCommandInterpreterRunOptions();
bool
GetStopOnContinue () const;
void
SetStopOnContinue (bool);
bool
GetStopOnError () const;
void
SetStopOnError (bool);
bool
GetStopOnCrash () const;
void
SetStopOnCrash (bool);
bool
GetEchoCommands () const;
void
SetEchoCommands (bool);
bool
GetPrintResults () const;
void
SetPrintResults (bool);
bool
GetAddToHistory () const;
void
SetAddToHistory (bool);
private:
lldb_private::CommandInterpreterRunOptions *
get () const;
lldb_private::CommandInterpreterRunOptions &
ref () const;
// This is set in the constructor and will always be valid.
mutable std::unique_ptr<lldb_private::CommandInterpreterRunOptions> m_opaque_up;
};
class SBCommandInterpreter
{
public:

View File

@ -27,6 +27,7 @@ public:
void SetIsDone(bool);
bool IsActive() const;
};
class SBDebugger
{
public:
@ -321,6 +322,12 @@ public:
RunCommandInterpreter (bool auto_handle_events,
bool spawn_thread);
void
RunCommandInterpreter (bool auto_handle_events,
bool spawn_thread,
SBCommandInterpreterRunOptions &options,
int &num_errors,
bool &quit_requested);
private:
friend class SBCommandInterpreter;

View File

@ -35,6 +35,7 @@ class LLDB_API SBBreakpointLocation;
class LLDB_API SBBroadcaster;
class LLDB_API SBCommand;
class LLDB_API SBCommandInterpreter;
class LLDB_API SBCommandInterpreterRunOptions;
class LLDB_API SBCommandPluginInterface;
class LLDB_API SBCommandReturnObject;
class LLDB_API SBCommunication;

View File

@ -28,12 +28,181 @@
namespace lldb_private {
class CommandInterpreterRunOptions
{
public:
//------------------------------------------------------------------
/// Construct a CommandInterpreterRunOptions object.
/// This class is used to control all the instances where we run multiple commands, e.g.
/// HandleCommands, HandleCommandsFromFile, RunCommandInterpreter.
/// The meanings of the options in this object are:
///
/// @param[in] stop_on_continue
/// If \b true execution will end on the first command that causes the process in the
/// execution context to continue. If \false, we won't check the execution status.
/// @param[in] stop_on_error
/// If \b true execution will end on the first command that causes an error.
/// @param[in] stop_on_crash
/// If \b true when a command causes the target to run, and the end of the run is a
/// signal or exception, stop executing the commands.
/// @param[in] echo_commands
/// If \b true echo the command before executing it. If \false, execute silently.
/// @param[in] print_results
/// If \b true print the results of the command after executing it. If \false, execute silently.
/// @param[in] add_to_history
/// If \b true add the commands to the command history. If \false, don't add them.
//------------------------------------------------------------------
CommandInterpreterRunOptions (LazyBool stop_on_continue,
LazyBool stop_on_error,
LazyBool stop_on_crash,
LazyBool echo_commands,
LazyBool print_results,
LazyBool add_to_history) :
m_stop_on_continue(stop_on_continue),
m_stop_on_error(stop_on_error),
m_stop_on_crash(stop_on_crash),
m_echo_commands(echo_commands),
m_print_results(print_results),
m_add_to_history(add_to_history)
{}
CommandInterpreterRunOptions () :
m_stop_on_continue(eLazyBoolCalculate),
m_stop_on_error(eLazyBoolCalculate),
m_stop_on_crash(eLazyBoolCalculate),
m_echo_commands(eLazyBoolCalculate),
m_print_results(eLazyBoolCalculate),
m_add_to_history(eLazyBoolCalculate)
{}
void
SetSilent (bool silent)
{
LazyBool value = silent ? eLazyBoolNo : eLazyBoolYes;
m_echo_commands = value;
m_print_results = value;
m_add_to_history = value;
}
// These return the default behaviors if the behavior is not eLazyBoolCalculate.
// But I've also left the ivars public since for different ways of running the
// interpreter you might want to force different defaults... In that case, just grab
// the LazyBool ivars directly and do what you want with eLazyBoolCalculate.
bool
GetStopOnContinue () const
{
return DefaultToNo (m_stop_on_continue);
}
void
SetStopOnContinue (bool stop_on_continue)
{
m_stop_on_continue = stop_on_continue ? eLazyBoolYes : eLazyBoolNo;
}
bool
GetStopOnError () const
{
return DefaultToNo (m_stop_on_continue);
}
void
SetStopOnError (bool stop_on_error)
{
m_stop_on_error = stop_on_error ? eLazyBoolYes : eLazyBoolNo;
}
bool
GetStopOnCrash () const
{
return DefaultToNo (m_stop_on_crash);
}
void
SetStopOnCrash (bool stop_on_crash)
{
m_stop_on_crash = stop_on_crash ? eLazyBoolYes : eLazyBoolNo;
}
bool
GetEchoCommands () const
{
return DefaultToYes (m_echo_commands);
}
void
SetEchoCommands (bool echo_commands)
{
m_echo_commands = echo_commands ? eLazyBoolYes : eLazyBoolNo;
}
bool
GetPrintResults () const
{
return DefaultToYes (m_print_results);
}
void
SetPrintResults (bool print_results)
{
m_print_results = print_results ? eLazyBoolYes : eLazyBoolNo;
}
bool
GetAddToHistory () const
{
return DefaultToYes (m_add_to_history);
}
void
SetAddToHistory (bool add_to_history)
{
m_add_to_history = add_to_history ? eLazyBoolYes : eLazyBoolNo;
}
LazyBool m_stop_on_continue;
LazyBool m_stop_on_error;
LazyBool m_stop_on_crash;
LazyBool m_echo_commands;
LazyBool m_print_results;
LazyBool m_add_to_history;
private:
static bool
DefaultToYes (LazyBool flag)
{
switch (flag)
{
case eLazyBoolCalculate:
case eLazyBoolYes:
return true;
case eLazyBoolNo:
return false;
}
}
static bool
DefaultToNo (LazyBool flag)
{
switch (flag)
{
case eLazyBoolYes:
return true;
case eLazyBoolCalculate:
case eLazyBoolNo:
return false;
}
}
};
class CommandInterpreter :
public Broadcaster,
public Properties,
public IOHandlerDelegate
{
public:
typedef std::map<std::string, OptionArgVectorSP> OptionArgMap;
enum
@ -168,27 +337,17 @@ public:
/// @param[in/out] context
/// The execution context in which to run the commands. Can be NULL in which case the default
/// context will be used.
/// @param[in] stop_on_continue
/// If \b true execution will end on the first command that causes the process in the
/// execution context to continue. If \false, we won't check the execution status.
/// @param[in] stop_on_error
/// If \b true execution will end on the first command that causes an error.
/// @param[in] echo_commands
/// If \b true echo the command before executing it. If \false, execute silently.
/// @param[in] print_results
/// If \b true print the results of the command after executing it. If \false, execute silently.
/// @param[out] result
/// @param[in] options
/// This object holds the options used to control when to stop, whether to execute commands,
/// etc.
/// @param[out] result
/// This is marked as succeeding with no output if all commands execute safely,
/// and failed with some explanation if we aborted executing the commands at some point.
//------------------------------------------------------------------
void
HandleCommands (const StringList &commands,
ExecutionContext *context,
bool stop_on_continue,
bool stop_on_error,
bool echo_commands,
bool print_results,
LazyBool add_to_history,
ExecutionContext *context,
CommandInterpreterRunOptions &options,
CommandReturnObject &result);
//------------------------------------------------------------------
@ -199,27 +358,17 @@ public:
/// @param[in/out] context
/// The execution context in which to run the commands. Can be NULL in which case the default
/// context will be used.
/// @param[in] stop_on_continue
/// If \b true execution will end on the first command that causes the process in the
/// execution context to continue. If \false, we won't check the execution status.
/// @param[in] stop_on_error
/// If \b true execution will end on the first command that causes an error.
/// @param[in] echo_commands
/// If \b true echo the command before executing it. If \false, execute silently.
/// @param[in] print_results
/// If \b true print the results of the command after executing it. If \false, execute silently.
/// @param[out] result
/// @param[in] options
/// This object holds the options used to control when to stop, whether to execute commands,
/// etc.
/// @param[out] result
/// This is marked as succeeding with no output if all commands execute safely,
/// and failed with some explanation if we aborted executing the commands at some point.
//------------------------------------------------------------------
void
HandleCommandsFromFile (FileSpec &file,
ExecutionContext *context,
LazyBool stop_on_continue,
LazyBool stop_on_error,
LazyBool echo_commands,
LazyBool print_results,
LazyBool add_to_history,
ExecutionContext *context,
CommandInterpreterRunOptions &options,
CommandReturnObject &result);
CommandObject *
@ -442,8 +591,8 @@ public:
void
RunCommandInterpreter (bool auto_handle_events,
bool spawn_thread);
bool spawn_thread,
CommandInterpreterRunOptions &options);
void
GetLLDBCommandsFromIOHandler (const char *prompt,
IOHandlerDelegate &delegate,
@ -467,6 +616,18 @@ public:
bool
GetStopCmdSourceOnError () const;
uint32_t
GetNumErrors() const
{
return m_num_errors;
}
bool
GetQuitRequested () const
{
return m_quit_requested;
}
protected:
friend class Debugger;
@ -522,6 +683,8 @@ private:
ChildrenTruncatedWarningStatus m_truncation_warning; // Whether we truncated children and whether the user has been told
uint32_t m_command_source_depth;
std::vector<uint32_t> m_command_source_flags;
uint32_t m_num_errors;
bool m_quit_requested;
};

View File

@ -62,6 +62,7 @@ class ClangPersistentVariables;
class ClangUserExpression;
class ClangUtilityFunction;
class CommandInterpreter;
class CommandInterpreterRunOptions;
class CommandObject;
class CommandReturnObject;
class Communication;

View File

@ -9,6 +9,71 @@
namespace lldb {
%feature("docstring",
"SBCommandInterpreterRunOptions controls how the RunCommandInterpreter runs the code it is fed.
A default SBCommandInterpreterRunOptions object has:
StopOnContinue: false
StopOnError: false
StopOnCrash: false
EchoCommands: true
PrintResults: true
AddToHistory: true
") SBCommandInterpreterRunOptions;
class SBCommandInterpreterRunOptions
{
friend class SBDebugger;
public:
SBCommandInterpreterRunOptions();
~SBCommandInterpreterRunOptions();
bool
GetStopOnContinue () const;
void
SetStopOnContinue (bool);
bool
GetStopOnError () const;
void
SetStopOnError (bool);
bool
GetStopOnCrash () const;
void
SetStopOnCrash (bool);
bool
GetEchoCommands () const;
void
SetEchoCommands (bool);
bool
GetPrintResults () const;
void
SetPrintResults (bool);
bool
GetAddToHistory () const;
void
SetAddToHistory (bool);
private:
lldb_private::CommandInterpreterRunOptions *
get () const;
lldb_private::CommandInterpreterRunOptions &
ref () const;
// This is set in the constructor and will always be valid.
mutable std::unique_ptr<lldb_private::CommandInterpreterRunOptions> m_opaque_up;
};
%feature("docstring",
"SBCommandInterpreter handles/interprets commands for lldb. You get the
command interpreter from the SBDebugger instance. For example (from test/

View File

@ -363,11 +363,13 @@ public:
lldb::SBTypeSynthetic
GetSyntheticForType (lldb::SBTypeNameSpecifier);
void
RunCommandInterpreter (bool auto_handle_events,
bool spawn_thread);
bool spawn_thread,
SBCommandInterpreterRunOptions &options,
int &num_errors,
bool &quit_requested);
}; // class SBDebugger
} // namespace lldb

View File

@ -29,6 +29,100 @@
using namespace lldb;
using namespace lldb_private;
SBCommandInterpreterRunOptions::SBCommandInterpreterRunOptions()
{
m_opaque_up.reset(new CommandInterpreterRunOptions());
}
SBCommandInterpreterRunOptions::~SBCommandInterpreterRunOptions()
{
}
bool
SBCommandInterpreterRunOptions::GetStopOnContinue () const
{
return m_opaque_up->GetStopOnContinue();
}
void
SBCommandInterpreterRunOptions::SetStopOnContinue (bool stop_on_continue)
{
m_opaque_up->SetStopOnContinue(stop_on_continue);
}
bool
SBCommandInterpreterRunOptions::GetStopOnError () const
{
return m_opaque_up->GetStopOnError();
}
void
SBCommandInterpreterRunOptions::SetStopOnError (bool stop_on_error)
{
m_opaque_up->SetStopOnError(stop_on_error);
}
bool
SBCommandInterpreterRunOptions::GetStopOnCrash () const
{
return m_opaque_up->GetStopOnCrash();
}
void
SBCommandInterpreterRunOptions::SetStopOnCrash (bool stop_on_crash)
{
m_opaque_up->SetStopOnCrash(stop_on_crash);
}
bool
SBCommandInterpreterRunOptions::GetEchoCommands () const
{
return m_opaque_up->GetEchoCommands();
}
void
SBCommandInterpreterRunOptions::SetEchoCommands (bool echo_commands)
{
m_opaque_up->SetEchoCommands(echo_commands);
}
bool
SBCommandInterpreterRunOptions::GetPrintResults () const
{
return m_opaque_up->GetPrintResults();
}
void
SBCommandInterpreterRunOptions::SetPrintResults (bool print_results)
{
m_opaque_up->SetPrintResults(print_results);
}
bool
SBCommandInterpreterRunOptions::GetAddToHistory () const
{
return m_opaque_up->GetAddToHistory();
}
void
SBCommandInterpreterRunOptions::SetAddToHistory (bool add_to_history)
{
m_opaque_up->SetAddToHistory(add_to_history);
}
lldb_private::CommandInterpreterRunOptions *
SBCommandInterpreterRunOptions::get () const
{
return m_opaque_up.get();
}
lldb_private::CommandInterpreterRunOptions &
SBCommandInterpreterRunOptions::ref () const
{
return *m_opaque_up.get();
}
class CommandPluginInterfaceImplementation : public CommandObjectParsed
{
public:

View File

@ -972,7 +972,30 @@ SBDebugger::RunCommandInterpreter (bool auto_handle_events,
bool spawn_thread)
{
if (m_opaque_sp)
m_opaque_sp->GetCommandInterpreter().RunCommandInterpreter(auto_handle_events, spawn_thread);
{
CommandInterpreterRunOptions options;
m_opaque_sp->GetCommandInterpreter().RunCommandInterpreter(auto_handle_events,
spawn_thread,
options);
}
}
void
SBDebugger::RunCommandInterpreter (bool auto_handle_events,
bool spawn_thread,
SBCommandInterpreterRunOptions &options,
int &num_errors,
bool &quit_requested)
{
if (m_opaque_sp)
{
CommandInterpreter &interp = m_opaque_sp->GetCommandInterpreter();
interp.RunCommandInterpreter(auto_handle_events, spawn_thread, options.ref());
num_errors = interp.GetNumErrors();
quit_requested = interp.GetQuitRequested();
}
}
void

View File

@ -307,17 +307,16 @@ one command per line.\n" );
result.SetImmediateOutputStream (output_stream);
result.SetImmediateErrorStream (error_stream);
bool stop_on_continue = true;
bool echo_commands = false;
bool print_results = true;
CommandInterpreterRunOptions options;
options.SetStopOnContinue(true);
options.SetStopOnError (data->stop_on_error);
options.SetEchoCommands (true);
options.SetPrintResults (true);
options.SetAddToHistory (false);
debugger.GetCommandInterpreter().HandleCommands (commands,
debugger.GetCommandInterpreter().HandleCommands (commands,
&exe_ctx,
stop_on_continue,
data->stop_on_error,
echo_commands,
print_results,
eLazyBoolNo,
options,
result);
result.GetImmediateOutputStream()->Flush();
result.GetImmediateErrorStream()->Flush();

View File

@ -387,14 +387,15 @@ protected:
m_options.m_stop_on_continue.OptionWasSet())
{
// Use user set settings
LazyBool print_command = m_options.m_silent_run.GetCurrentValue() ? eLazyBoolNo : eLazyBoolYes;
CommandInterpreterRunOptions options;
options.SetStopOnContinue(m_options.m_stop_on_continue.GetCurrentValue());
options.SetStopOnError (m_options.m_stop_on_error.GetCurrentValue());
options.SetEchoCommands (m_options.m_silent_run.GetCurrentValue());
options.SetPrintResults (m_options.m_silent_run.GetCurrentValue());
m_interpreter.HandleCommandsFromFile (cmd_file,
exe_ctx,
m_options.m_stop_on_continue.GetCurrentValue() ? eLazyBoolYes : eLazyBoolNo, // Stop on continue
m_options.m_stop_on_error.GetCurrentValue() ? eLazyBoolYes : eLazyBoolNo, // Stop on error
print_command, // Echo command
print_command, // Print command output
eLazyBoolCalculate, // Add to history
options,
result);
}
@ -402,13 +403,10 @@ protected:
{
// No options were set, inherit any settings from nested "command source" commands,
// or set to sane default settings...
CommandInterpreterRunOptions options;
m_interpreter.HandleCommandsFromFile (cmd_file,
exe_ctx,
eLazyBoolCalculate, // Stop on continue
eLazyBoolCalculate, // Stop on error
eLazyBoolCalculate, // Echo command
eLazyBoolCalculate, // Print command output
eLazyBoolCalculate, // Add to history
options,
result);
}

View File

@ -279,17 +279,16 @@ but do NOT enter more than one command per line. \n" );
result.SetImmediateOutputStream (output_stream);
result.SetImmediateErrorStream (error_stream);
bool stop_on_continue = true;
bool echo_commands = false;
bool print_results = true;
CommandInterpreterRunOptions options;
options.SetStopOnContinue (true);
options.SetStopOnError (data->stop_on_error);
options.SetEchoCommands (false);
options.SetPrintResults (true);
options.SetAddToHistory (false);
debugger.GetCommandInterpreter().HandleCommands (commands,
&exe_ctx,
stop_on_continue,
data->stop_on_error,
echo_commands,
print_results,
eLazyBoolNo,
options,
result);
result.GetImmediateOutputStream()->Flush();
result.GetImmediateErrorStream()->Flush();

View File

@ -165,6 +165,7 @@ ClangExpressionParser::ClangExpressionParser (ExecutionContextScope *exe_scope,
case lldb::eLanguageTypeC_plus_plus:
m_compiler->getLangOpts().CPlusPlus = true;
m_compiler->getLangOpts().CPlusPlus11 = true;
m_compiler->getHeaderSearchOpts().UseLibcxx = true;
break;
case lldb::eLanguageTypeObjC_plus_plus:
default:
@ -172,6 +173,7 @@ ClangExpressionParser::ClangExpressionParser (ExecutionContextScope *exe_scope,
m_compiler->getLangOpts().ObjC2 = true;
m_compiler->getLangOpts().CPlusPlus = true;
m_compiler->getLangOpts().CPlusPlus11 = true;
m_compiler->getHeaderSearchOpts().UseLibcxx = true;
break;
}

View File

@ -119,7 +119,10 @@ CommandInterpreter::CommandInterpreter
m_comment_char ('#'),
m_batch_command_mode (false),
m_truncation_warning(eNoTruncation),
m_command_source_depth (0)
m_command_source_depth (0),
m_num_errors(0),
m_quit_requested(false)
{
debugger.SetScriptLanguage (script_language);
SetEventName (eBroadcastBitThreadShouldExit, "thread-should-exit");
@ -2421,13 +2424,14 @@ CommandInterpreter::SourceInitFile (bool in_cwd, CommandReturnObject &result)
if (init_file.Exists())
{
const bool saved_batch = SetBatchCommandMode (true);
CommandInterpreterRunOptions options;
options.SetSilent (true);
options.SetStopOnError (false);
options.SetStopOnContinue (true);
HandleCommandsFromFile (init_file,
nullptr, // Execution context
eLazyBoolYes, // Stop on continue
eLazyBoolNo, // Stop on error
eLazyBoolNo, // Don't echo commands
eLazyBoolNo, // Don't print command output
eLazyBoolNo, // Don't add the commands that are sourced into the history buffer
options,
result);
SetBatchCommandMode (saved_batch);
}
@ -2457,12 +2461,8 @@ CommandInterpreter::GetPlatform (bool prefer_target_platform)
void
CommandInterpreter::HandleCommands (const StringList &commands,
ExecutionContext *override_context,
bool stop_on_continue,
bool stop_on_error,
bool echo_commands,
bool print_results,
LazyBool add_to_history,
ExecutionContext *override_context,
CommandInterpreterRunOptions &options,
CommandReturnObject &result)
{
size_t num_lines = commands.GetSize();
@ -2478,7 +2478,7 @@ CommandInterpreter::HandleCommands (const StringList &commands,
if (override_context != nullptr)
UpdateExecutionContext (override_context);
if (!stop_on_continue)
if (!options.GetStopOnContinue())
{
m_debugger.SetAsyncExecution (false);
}
@ -2489,7 +2489,7 @@ CommandInterpreter::HandleCommands (const StringList &commands,
if (cmd[0] == '\0')
continue;
if (echo_commands)
if (options.GetEchoCommands())
{
result.AppendMessageWithFormat ("%s %s\n",
m_debugger.GetPrompt(),
@ -2502,16 +2502,16 @@ CommandInterpreter::HandleCommands (const StringList &commands,
// We might call into a regex or alias command, in which case the add_to_history will get lost. This
// m_command_source_depth dingus is the way we turn off adding to the history in that case, so set it up here.
if (!add_to_history)
if (!options.GetAddToHistory())
m_command_source_depth++;
bool success = HandleCommand(cmd, add_to_history, tmp_result,
bool success = HandleCommand(cmd, options.m_add_to_history, tmp_result,
nullptr, /* override_context */
true, /* repeat_on_empty_command */
override_context != nullptr /* no_context_switching */);
if (!add_to_history)
if (!options.GetAddToHistory())
m_command_source_depth--;
if (print_results)
if (options.GetPrintResults())
{
if (tmp_result.Succeeded())
result.AppendMessageWithFormat("%s", tmp_result.GetOutputData());
@ -2522,7 +2522,7 @@ CommandInterpreter::HandleCommands (const StringList &commands,
const char *error_msg = tmp_result.GetErrorData();
if (error_msg == nullptr || error_msg[0] == '\0')
error_msg = "<unknown error>.\n";
if (stop_on_error)
if (options.GetStopOnError())
{
result.AppendErrorWithFormat("Aborting reading of commands after command #%" PRIu64 ": '%s' failed with %s",
(uint64_t)idx, cmd, error_msg);
@ -2530,7 +2530,7 @@ CommandInterpreter::HandleCommands (const StringList &commands,
m_debugger.SetAsyncExecution (old_async_execution);
return;
}
else if (print_results)
else if (options.GetPrintResults())
{
result.AppendMessageWithFormat ("Command #%" PRIu64 " '%s' failed with %s",
(uint64_t)idx + 1,
@ -2551,7 +2551,7 @@ CommandInterpreter::HandleCommands (const StringList &commands,
if ((tmp_result.GetStatus() == eReturnStatusSuccessContinuingNoResult)
|| (tmp_result.GetStatus() == eReturnStatusSuccessContinuingResult))
{
if (stop_on_continue)
if (options.GetStopOnContinue())
{
// If we caused the target to proceed, and we're going to stop in that case, set the
// status in our real result before returning. This is an error if the continue was not the
@ -2582,17 +2582,14 @@ enum {
eHandleCommandFlagStopOnContinue = (1u << 0),
eHandleCommandFlagStopOnError = (1u << 1),
eHandleCommandFlagEchoCommand = (1u << 2),
eHandleCommandFlagPrintResult = (1u << 3)
eHandleCommandFlagPrintResult = (1u << 3),
eHandleCommandFlagStopOnCrash = (1u << 4)
};
void
CommandInterpreter::HandleCommandsFromFile (FileSpec &cmd_file,
ExecutionContext *context,
LazyBool stop_on_continue,
LazyBool stop_on_error,
LazyBool echo_command,
LazyBool print_result,
LazyBool add_to_history,
CommandInterpreterRunOptions &options,
CommandReturnObject &result)
{
if (cmd_file.Exists())
@ -2608,7 +2605,7 @@ CommandInterpreter::HandleCommandsFromFile (FileSpec &cmd_file,
uint32_t flags = 0;
if (stop_on_continue == eLazyBoolCalculate)
if (options.m_stop_on_continue == eLazyBoolCalculate)
{
if (m_command_source_flags.empty())
{
@ -2620,12 +2617,12 @@ CommandInterpreter::HandleCommandsFromFile (FileSpec &cmd_file,
flags |= eHandleCommandFlagStopOnContinue;
}
}
else if (stop_on_continue == eLazyBoolYes)
else if (options.m_stop_on_continue == eLazyBoolYes)
{
flags |= eHandleCommandFlagStopOnContinue;
}
if (stop_on_error == eLazyBoolCalculate)
if (options.m_stop_on_error == eLazyBoolCalculate)
{
if (m_command_source_flags.empty())
{
@ -2637,12 +2634,12 @@ CommandInterpreter::HandleCommandsFromFile (FileSpec &cmd_file,
flags |= eHandleCommandFlagStopOnError;
}
}
else if (stop_on_error == eLazyBoolYes)
else if (options.m_stop_on_error == eLazyBoolYes)
{
flags |= eHandleCommandFlagStopOnError;
}
if (echo_command == eLazyBoolCalculate)
if (options.m_echo_commands == eLazyBoolCalculate)
{
if (m_command_source_flags.empty())
{
@ -2654,12 +2651,12 @@ CommandInterpreter::HandleCommandsFromFile (FileSpec &cmd_file,
flags |= eHandleCommandFlagEchoCommand;
}
}
else if (echo_command == eLazyBoolYes)
else if (options.m_echo_commands == eLazyBoolYes)
{
flags |= eHandleCommandFlagEchoCommand;
}
if (print_result == eLazyBoolCalculate)
if (options.m_print_results == eLazyBoolCalculate)
{
if (m_command_source_flags.empty())
{
@ -2671,7 +2668,7 @@ CommandInterpreter::HandleCommandsFromFile (FileSpec &cmd_file,
flags |= eHandleCommandFlagPrintResult;
}
}
else if (print_result == eLazyBoolYes)
else if (options.m_print_results == eLazyBoolYes)
{
flags |= eHandleCommandFlagPrintResult;
}
@ -3062,11 +3059,13 @@ CommandInterpreter::IOHandlerInputComplete (IOHandler &io_handler, std::string &
break;
case eReturnStatusFailed:
m_num_errors++;
if (io_handler.GetFlags().Test(eHandleCommandFlagStopOnError))
io_handler.SetIsDone(true);
break;
case eReturnStatusQuit:
m_quit_requested = true;
io_handler.SetIsDone(true);
break;
}
@ -3149,19 +3148,36 @@ CommandInterpreter::IsActive ()
void
CommandInterpreter::RunCommandInterpreter(bool auto_handle_events,
bool spawn_thread)
bool spawn_thread,
CommandInterpreterRunOptions &options)
{
// Only get one line at a time
const bool multiple_lines = false;
m_num_errors = 0;
m_quit_requested = false;
// Always re-create the IOHandlerEditline in case the input
// changed. The old instance might have had a non-interactive
// input and now it does or vice versa.
uint32_t flags= 0;
if (options.m_stop_on_continue == eLazyBoolYes)
flags |= eHandleCommandFlagStopOnContinue;
if (options.m_stop_on_error == eLazyBoolYes)
flags |= eHandleCommandFlagStopOnError;
if (options.m_stop_on_crash == eLazyBoolYes)
flags |= eHandleCommandFlagStopOnCrash;
if (options.m_echo_commands != eLazyBoolNo)
flags |= eHandleCommandFlagEchoCommand;
if (options.m_print_results != eLazyBoolNo)
flags |= eHandleCommandFlagPrintResult;
m_command_io_handler_sp.reset(new IOHandlerEditline (m_debugger,
m_debugger.GetInputFile(),
m_debugger.GetOutputFile(),
m_debugger.GetErrorFile(),
eHandleCommandFlagEchoCommand | eHandleCommandFlagPrintResult,
flags,
"lldb",
m_debugger.GetPrompt(),
multiple_lines,

View File

@ -2178,18 +2178,17 @@ Target::RunStopHooks ()
if (print_thread_header)
result.AppendMessageWithFormat("-- Thread %d\n", exc_ctx_with_reasons[i].GetThreadPtr()->GetIndexID());
bool stop_on_continue = true;
bool stop_on_error = true;
bool echo_commands = false;
bool print_results = true;
GetDebugger().GetCommandInterpreter().HandleCommands (cur_hook_sp->GetCommands(),
&exc_ctx_with_reasons[i],
stop_on_continue,
stop_on_error,
echo_commands,
print_results,
eLazyBoolNo,
CommandInterpreterRunOptions options;
options.SetStopOnContinue (true);
options.SetStopOnError (true);
options.SetEchoCommands (false);
options.SetPrintResults (true);
options.SetAddToHistory (false);
GetDebugger().GetCommandInterpreter().HandleCommands (cur_hook_sp->GetCommands(),
&exc_ctx_with_reasons[i],
options,
result);
// If the command started the target going again, we should bag out of

View File

@ -514,6 +514,7 @@
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "";
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 330.99.0;
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
@ -659,7 +660,7 @@
CLANG_CXX_LIBRARY = "libc++";
"CODE_SIGN_ENTITLEMENTS[sdk=iphoneos*]" = "source/debugserver-entitlements.plist";
"CODE_SIGN_ENTITLEMENTS[sdk=macosx*]" = "source/debugserver-macosx-entitlements.plist";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "-";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "";
COPY_PHASE_STRIP = YES;
CURRENT_PROJECT_VERSION = 330.99.0;
@ -726,7 +727,7 @@
CLANG_CXX_LIBRARY = "libc++";
"CODE_SIGN_ENTITLEMENTS[sdk=iphoneos*]" = "source/debugserver-entitlements.plist";
"CODE_SIGN_ENTITLEMENTS[sdk=macosx*]" = "source/debugserver-macosx-entitlements.plist";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "-";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "";
COPY_PHASE_STRIP = YES;
CURRENT_PROJECT_VERSION = 330.99.0;
@ -803,6 +804,7 @@
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "";
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 330.99.0;
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
@ -824,7 +826,7 @@
CLANG_CXX_LIBRARY = "libc++";
"CODE_SIGN_ENTITLEMENTS[sdk=iphoneos*]" = "source/debugserver-entitlements.plist";
"CODE_SIGN_ENTITLEMENTS[sdk=macosx*]" = "source/debugserver-macosx-entitlements.plist";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "-";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "";
COPY_PHASE_STRIP = YES;
CURRENT_PROJECT_VERSION = 330.99.0;

View File

@ -921,6 +921,9 @@ Driver::MainLoop ()
// so we can then run the command interpreter using the file contents.
const char *commands_data = commands_stream.GetData();
const size_t commands_size = commands_stream.GetSize();
// The command file might have requested that we quit, this variable will track that.
bool quit_requested = false;
if (commands_data && commands_size)
{
enum PIPES { READ, WRITE }; // Constants 0 and 1 for READ and WRITE
@ -961,7 +964,18 @@ Driver::MainLoop ()
fds[READ] = -1; // The FILE * 'commands_file' now owns the read descriptor
// Hand ownership if the FILE * over to the debugger for "commands_file".
m_debugger.SetInputFileHandle (commands_file, true);
m_debugger.RunCommandInterpreter(handle_events, spawn_thread);
// Set the debugger into Sync mode when running the command file. Otherwise command files
// that run the target won't run in a sensible way.
bool old_async = m_debugger.GetAsync();
m_debugger.SetAsync(false);
int num_errors;
SBCommandInterpreterRunOptions options;
options.SetStopOnError (true);
m_debugger.RunCommandInterpreter(handle_events, spawn_thread, options, num_errors, quit_requested);
m_debugger.SetAsync(old_async);
}
else
{
@ -1015,8 +1029,12 @@ Driver::MainLoop ()
// Now set the input file handle to STDIN and run the command
// interpreter again in interactive mode and let the debugger
// take ownership of stdin
m_debugger.SetInputFileHandle (stdin, true);
m_debugger.RunCommandInterpreter(handle_events, spawn_thread);
if (!quit_requested)
{
m_debugger.SetInputFileHandle (stdin, true);
m_debugger.RunCommandInterpreter(handle_events, spawn_thread);
}
reset_stdin_termios();
fclose (stdin);