diff options
-rw-r--r-- | lldb/include/lldb/API/SBCommandInterpreter.h | 53 | ||||
-rw-r--r-- | lldb/include/lldb/API/SBDebugger.h | 7 | ||||
-rw-r--r-- | lldb/include/lldb/API/SBDefines.h | 1 | ||||
-rw-r--r-- | lldb/include/lldb/Interpreter/CommandInterpreter.h | 231 | ||||
-rw-r--r-- | lldb/include/lldb/lldb-forward.h | 1 | ||||
-rw-r--r-- | lldb/scripts/Python/interface/SBCommandInterpreter.i | 65 | ||||
-rw-r--r-- | lldb/scripts/Python/interface/SBDebugger.i | 8 | ||||
-rw-r--r-- | lldb/source/API/SBCommandInterpreter.cpp | 94 | ||||
-rw-r--r-- | lldb/source/API/SBDebugger.cpp | 25 | ||||
-rw-r--r-- | lldb/source/Commands/CommandObjectBreakpointCommand.cpp | 19 | ||||
-rw-r--r-- | lldb/source/Commands/CommandObjectCommands.cpp | 20 | ||||
-rw-r--r-- | lldb/source/Commands/CommandObjectWatchpointCommand.cpp | 15 | ||||
-rw-r--r-- | lldb/source/Expression/ClangExpressionParser.cpp | 2 | ||||
-rw-r--r-- | lldb/source/Interpreter/CommandInterpreter.cpp | 90 | ||||
-rw-r--r-- | lldb/source/Target/Target.cpp | 23 | ||||
-rw-r--r-- | lldb/tools/debugserver/debugserver.xcodeproj/project.pbxproj | 8 | ||||
-rw-r--r-- | lldb/tools/driver/Driver.cpp | 24 |
17 files changed, 564 insertions, 122 deletions
diff --git a/lldb/include/lldb/API/SBCommandInterpreter.h b/lldb/include/lldb/API/SBCommandInterpreter.h index 737e1b10848..6f9295bf740 100644 --- a/lldb/include/lldb/API/SBCommandInterpreter.h +++ b/lldb/include/lldb/API/SBCommandInterpreter.h @@ -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: diff --git a/lldb/include/lldb/API/SBDebugger.h b/lldb/include/lldb/API/SBDebugger.h index 2386ffc968d..de7d1a1c23b 100644 --- a/lldb/include/lldb/API/SBDebugger.h +++ b/lldb/include/lldb/API/SBDebugger.h @@ -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; diff --git a/lldb/include/lldb/API/SBDefines.h b/lldb/include/lldb/API/SBDefines.h index 646417eef20..244bd474940 100644 --- a/lldb/include/lldb/API/SBDefines.h +++ b/lldb/include/lldb/API/SBDefines.h @@ -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; diff --git a/lldb/include/lldb/Interpreter/CommandInterpreter.h b/lldb/include/lldb/Interpreter/CommandInterpreter.h index c33d71a6dbb..7047f21e716 100644 --- a/lldb/include/lldb/Interpreter/CommandInterpreter.h +++ b/lldb/include/lldb/Interpreter/CommandInterpreter.h @@ -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; }; diff --git a/lldb/include/lldb/lldb-forward.h b/lldb/include/lldb/lldb-forward.h index 0f95fc9f383..c3e093fce11 100644 --- a/lldb/include/lldb/lldb-forward.h +++ b/lldb/include/lldb/lldb-forward.h @@ -62,6 +62,7 @@ class ClangPersistentVariables; class ClangUserExpression; class ClangUtilityFunction; class CommandInterpreter; +class CommandInterpreterRunOptions; class CommandObject; class CommandReturnObject; class Communication; diff --git a/lldb/scripts/Python/interface/SBCommandInterpreter.i b/lldb/scripts/Python/interface/SBCommandInterpreter.i index 9dc842e87c2..856038094f7 100644 --- a/lldb/scripts/Python/interface/SBCommandInterpreter.i +++ b/lldb/scripts/Python/interface/SBCommandInterpreter.i @@ -10,6 +10,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/ python_api/interpreter/TestCommandInterpreterAPI.py), diff --git a/lldb/scripts/Python/interface/SBDebugger.i b/lldb/scripts/Python/interface/SBDebugger.i index ba1c18914e3..fb63fc362dc 100644 --- a/lldb/scripts/Python/interface/SBDebugger.i +++ b/lldb/scripts/Python/interface/SBDebugger.i @@ -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 diff --git a/lldb/source/API/SBCommandInterpreter.cpp b/lldb/source/API/SBCommandInterpreter.cpp index 9f6f4e8d428..bc8d6d34aa9 100644 --- a/lldb/source/API/SBCommandInterpreter.cpp +++ b/lldb/source/API/SBCommandInterpreter.cpp @@ -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: diff --git a/lldb/source/API/SBDebugger.cpp b/lldb/source/API/SBDebugger.cpp index b53dec2a21d..a655950926f 100644 --- a/lldb/source/API/SBDebugger.cpp +++ b/lldb/source/API/SBDebugger.cpp @@ -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 diff --git a/lldb/source/Commands/CommandObjectBreakpointCommand.cpp b/lldb/source/Commands/CommandObjectBreakpointCommand.cpp index fdb87d11900..955c26f99d3 100644 --- a/lldb/source/Commands/CommandObjectBreakpointCommand.cpp +++ b/lldb/source/Commands/CommandObjectBreakpointCommand.cpp @@ -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; - - debugger.GetCommandInterpreter().HandleCommands (commands, + CommandInterpreterRunOptions options; + options.SetStopOnContinue(true); + options.SetStopOnError (data->stop_on_error); + options.SetEchoCommands (true); + 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(); diff --git a/lldb/source/Commands/CommandObjectCommands.cpp b/lldb/source/Commands/CommandObjectCommands.cpp index 836d2a18e35..c7341c27d8f 100644 --- a/lldb/source/Commands/CommandObjectCommands.cpp +++ b/lldb/source/Commands/CommandObjectCommands.cpp @@ -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); } diff --git a/lldb/source/Commands/CommandObjectWatchpointCommand.cpp b/lldb/source/Commands/CommandObjectWatchpointCommand.cpp index f46db7a6a82..275ee925adc 100644 --- a/lldb/source/Commands/CommandObjectWatchpointCommand.cpp +++ b/lldb/source/Commands/CommandObjectWatchpointCommand.cpp @@ -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(); diff --git a/lldb/source/Expression/ClangExpressionParser.cpp b/lldb/source/Expression/ClangExpressionParser.cpp index f32ca3ae216..98446bb6ad8 100644 --- a/lldb/source/Expression/ClangExpressionParser.cpp +++ b/lldb/source/Expression/ClangExpressionParser.cpp @@ -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; } diff --git a/lldb/source/Interpreter/CommandInterpreter.cpp b/lldb/source/Interpreter/CommandInterpreter.cpp index e42f52fdaa6..28eafcbd1d9 100644 --- a/lldb/source/Interpreter/CommandInterpreter.cpp +++ b/lldb/source/Interpreter/CommandInterpreter.cpp @@ -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, diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp index badbab3ff3e..6c2d270c0b2 100644 --- a/lldb/source/Target/Target.cpp +++ b/lldb/source/Target/Target.cpp @@ -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 diff --git a/lldb/tools/debugserver/debugserver.xcodeproj/project.pbxproj b/lldb/tools/debugserver/debugserver.xcodeproj/project.pbxproj index f9f0b6408d8..86ff4205439 100644 --- a/lldb/tools/debugserver/debugserver.xcodeproj/project.pbxproj +++ b/lldb/tools/debugserver/debugserver.xcodeproj/project.pbxproj @@ -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; diff --git a/lldb/tools/driver/Driver.cpp b/lldb/tools/driver/Driver.cpp index 0b5809c8355..e4fdc77caea 100644 --- a/lldb/tools/driver/Driver.cpp +++ b/lldb/tools/driver/Driver.cpp @@ -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); |