diff options
author | Jonathan Gray <jsg@cvs.openbsd.org> | 2021-05-01 00:43:13 +0000 |
---|---|---|
committer | Jonathan Gray <jsg@cvs.openbsd.org> | 2021-05-01 00:43:13 +0000 |
commit | 9f72b64eaacefae0bd746ca3158e1b34b8be6c48 (patch) | |
tree | 829990b735eb8496e3c82e988ddc256af054c7dc /gnu/llvm/lldb | |
parent | c9c613255725ec9c225e463b0b2af0daaafbd8e8 (diff) |
arvm7 -> armv7
Diffstat (limited to 'gnu/llvm/lldb')
-rw-r--r-- | gnu/llvm/lldb/docs/man/lldb.rst | 22 | ||||
-rw-r--r-- | gnu/llvm/lldb/tools/driver/Driver.cpp | 180 |
2 files changed, 117 insertions, 85 deletions
diff --git a/gnu/llvm/lldb/docs/man/lldb.rst b/gnu/llvm/lldb/docs/man/lldb.rst index b4972df1b60..97996322978 100644 --- a/gnu/llvm/lldb/docs/man/lldb.rst +++ b/gnu/llvm/lldb/docs/man/lldb.rst @@ -251,11 +251,16 @@ EXAMPLES The debugger can be started in several modes. -Passing an executable as a positional argument prepares :program:`lldb` to -debug the given executable. Arguments passed after -- are considered arguments -to the debugged executable. +Passing an executable as a positional argument prepares lldb to debug the given +executable. To disambiguate between arguments passed to lldb and arguments +passed to the debugged executable, arguments starting with a - must be passed +after --. - lldb --arch x86_64 /path/to/program -- --arch arvm7 + lldb --arch x86_64 /path/to/program program argument -- --arch armv7 + +For convenience, passing the executable after -- is also supported. + + lldb --arch x86_64 -- /path/to/program program argument --arch armv7 Passing one of the attach options causes :program:`lldb` to immediately attach to the given process. @@ -298,7 +303,14 @@ CONFIGURATION FILES ------------------- :program:`lldb` reads things like settings, aliases and commands from the -.lldbinit file. It will first look for ~/.lldbinit and load that first. +.lldbinit file. + +First, it will read the application specific init file whose name is +~/.lldbinit followed by a "-" and the name of the current program. This would +be ~/.lldbinit-lldb for the command line :program:`lldb` and ~/.lldbinit-Xcode +for Xcode. If there is no application specific init file, the global +~/.lldbinit is read. + Secondly, it will look for an .lldbinit file in the current working directory. For security reasons, :program:`lldb` will print a warning and not source this file by default. This behavior can be changed by changing the diff --git a/gnu/llvm/lldb/tools/driver/Driver.cpp b/gnu/llvm/lldb/tools/driver/Driver.cpp index 73874389aa1..4dceb3b4bdc 100644 --- a/gnu/llvm/lldb/tools/driver/Driver.cpp +++ b/gnu/llvm/lldb/tools/driver/Driver.cpp @@ -9,6 +9,7 @@ #include "Driver.h" #include "lldb/API/SBCommandInterpreter.h" +#include "lldb/API/SBCommandInterpreterRunOptions.h" #include "lldb/API/SBCommandReturnObject.h" #include "lldb/API/SBDebugger.h" #include "lldb/API/SBFile.h" @@ -360,13 +361,8 @@ SBError Driver::ProcessArgs(const opt::InputArgList &args, bool &exiting) { if (m_option_data.m_process_name.empty() && m_option_data.m_process_pid == LLDB_INVALID_PROCESS_ID) { - // If the option data args array is empty that means the file was not - // specified with -f and we need to get it from the input args. - if (m_option_data.m_args.empty()) { - if (auto *arg = args.getLastArgNoClaim(OPT_INPUT)) { - m_option_data.m_args.push_back(arg->getAsString((args))); - } - } + for (auto *arg : args.filtered(OPT_INPUT)) + m_option_data.m_args.push_back(arg->getAsString((args))); // Any argument following -- is an argument for the inferior. if (auto *arg = args.getLastArgNoClaim(OPT_REM)) { @@ -587,74 +583,75 @@ int Driver::MainLoop() { 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; - bool stopped_for_crash = false; + bool go_interactive = true; if ((commands_data != nullptr) && (commands_size != 0u)) { - bool success = true; FILE *commands_file = PrepareCommandsForSourcing(commands_data, commands_size); - if (commands_file != nullptr) { - m_debugger.SetInputFileHandle(commands_file, true); - - // 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 = 0; - - SBCommandInterpreterRunOptions options; - options.SetStopOnError(true); - if (m_option_data.m_batch) - options.SetStopOnCrash(true); - - m_debugger.RunCommandInterpreter(handle_events, spawn_thread, options, - num_errors, quit_requested, - stopped_for_crash); - - if (m_option_data.m_batch && stopped_for_crash && - !m_option_data.m_after_crash_commands.empty()) { - SBStream crash_commands_stream; - WriteCommandsForSourcing(eCommandPlacementAfterCrash, - crash_commands_stream); - const char *crash_commands_data = crash_commands_stream.GetData(); - const size_t crash_commands_size = crash_commands_stream.GetSize(); - commands_file = PrepareCommandsForSourcing(crash_commands_data, - crash_commands_size); - if (commands_file != nullptr) { - bool local_quit_requested; - bool local_stopped_for_crash; - m_debugger.SetInputFileHandle(commands_file, true); - - m_debugger.RunCommandInterpreter(handle_events, spawn_thread, options, - num_errors, local_quit_requested, - local_stopped_for_crash); - if (local_quit_requested) - quit_requested = true; - } - } - m_debugger.SetAsync(old_async); - } else - success = false; - // Something went wrong with command pipe - if (!success) { + if (commands_file == nullptr) { + // We should have already printed an error in PrepareCommandsForSourcing. exit(1); } - } - // Now set the input file handle to STDIN and run the command - // interpreter again in interactive mode or repl mode and let the debugger - // take ownership of stdin + m_debugger.SetInputFileHandle(commands_file, true); + + // 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); + + SBCommandInterpreterRunOptions options; + options.SetAutoHandleEvents(true); + options.SetSpawnThread(false); + options.SetStopOnError(true); + options.SetStopOnCrash(m_option_data.m_batch); + + SBCommandInterpreterRunResult results = + m_debugger.RunCommandInterpreter(options); + if (results.GetResult() == lldb::eCommandInterpreterResultQuitRequested) + go_interactive = false; + if (m_option_data.m_batch && + results.GetResult() != lldb::eCommandInterpreterResultInferiorCrash) + go_interactive = false; + + // When running in batch mode and stopped because of an error, exit with a + // non-zero exit status. + if (m_option_data.m_batch && + results.GetResult() == lldb::eCommandInterpreterResultCommandError) + exit(1); - bool go_interactive = true; - if (quit_requested) - go_interactive = false; - else if (m_option_data.m_batch && !stopped_for_crash) - go_interactive = false; + if (m_option_data.m_batch && + results.GetResult() == lldb::eCommandInterpreterResultInferiorCrash && + !m_option_data.m_after_crash_commands.empty()) { + SBStream crash_commands_stream; + WriteCommandsForSourcing(eCommandPlacementAfterCrash, + crash_commands_stream); + const char *crash_commands_data = crash_commands_stream.GetData(); + const size_t crash_commands_size = crash_commands_stream.GetSize(); + commands_file = + PrepareCommandsForSourcing(crash_commands_data, crash_commands_size); + if (commands_file != nullptr) { + m_debugger.SetInputFileHandle(commands_file, true); + SBCommandInterpreterRunResult local_results = + m_debugger.RunCommandInterpreter(options); + if (local_results.GetResult() == + lldb::eCommandInterpreterResultQuitRequested) + go_interactive = false; + + // When running in batch mode and an error occurred while sourcing + // the crash commands, exit with a non-zero exit status. + if (m_option_data.m_batch && + local_results.GetResult() == + lldb::eCommandInterpreterResultCommandError) + exit(1); + } + } + m_debugger.SetAsync(old_async); + } + // Now set the input file handle to STDIN and run the command interpreter + // again in interactive mode or repl mode and let the debugger take ownership + // of stdin. if (go_interactive) { m_debugger.SetInputFileHandle(stdin, true); @@ -763,10 +760,15 @@ EXAMPLES: The debugger can be started in several modes. Passing an executable as a positional argument prepares lldb to debug the - given executable. Arguments passed after -- are considered arguments to the - debugged executable. + given executable. To disambiguate between arguments passed to lldb and + arguments passed to the debugged executable, arguments starting with a - must + be passed after --. + + lldb --arch x86_64 /path/to/program program argument -- --arch armv7 + + For convenience, passing the executable after -- is also supported. - lldb --arch x86_64 /path/to/program -- --arch arvm7 + lldb --arch x86_64 -- /path/to/program program argument --arch armv7 Passing one of the attach options causes lldb to immediately attach to the given process. @@ -795,11 +797,12 @@ EXAMPLES: llvm::outs() << examples << '\n'; } -llvm::Optional<int> InitializeReproducer(opt::InputArgList &input_args) { +llvm::Optional<int> InitializeReproducer(llvm::StringRef argv0, + opt::InputArgList &input_args) { if (auto *replay_path = input_args.getLastArg(OPT_replay)) { - const bool skip_version_check = input_args.hasArg(OPT_skip_version_check); + const bool no_version_check = input_args.hasArg(OPT_no_version_check); if (const char *error = - SBReproducer::Replay(replay_path->getValue(), skip_version_check)) { + SBReproducer::Replay(replay_path->getValue(), no_version_check)) { WithColor::error() << "reproducer replay failed: " << error << '\n'; return 1; } @@ -807,9 +810,21 @@ llvm::Optional<int> InitializeReproducer(opt::InputArgList &input_args) { } bool capture = input_args.hasArg(OPT_capture); + bool generate_on_exit = input_args.hasArg(OPT_generate_on_exit); auto *capture_path = input_args.getLastArg(OPT_capture_path); + if (generate_on_exit && !capture) { + WithColor::warning() + << "-reproducer-generate-on-exit specified without -capture\n"; + } + if (capture || capture_path) { + // Register the reproducer signal handler. + if (!input_args.hasArg(OPT_no_generate_on_signal)) { + llvm::sys::AddSignalHandler(reproducer_handler, + const_cast<char *>(argv0.data())); + } + if (capture_path) { if (!capture) WithColor::warning() << "-capture-path specified without -capture\n"; @@ -824,6 +839,8 @@ llvm::Optional<int> InitializeReproducer(opt::InputArgList &input_args) { return 1; } } + if (generate_on_exit) + SBReproducer::SetAutoGenerate(true); } return llvm::None; @@ -840,24 +857,27 @@ int main(int argc, char const *argv[]) { unsigned MAC; ArrayRef<const char *> arg_arr = makeArrayRef(argv + 1, argc - 1); opt::InputArgList input_args = T.ParseArgs(arg_arr, MAI, MAC); + llvm::StringRef argv0 = llvm::sys::path::filename(argv[0]); if (input_args.hasArg(OPT_help)) { - printHelp(T, llvm::sys::path::filename(argv[0])); + printHelp(T, argv0); return 0; } - for (auto *arg : input_args.filtered(OPT_UNKNOWN)) { - WithColor::warning() << "ignoring unknown option: " << arg->getSpelling() - << '\n'; + // Error out on unknown options. + if (input_args.hasArg(OPT_UNKNOWN)) { + for (auto *arg : input_args.filtered(OPT_UNKNOWN)) { + WithColor::error() << "unknown option: " << arg->getSpelling() << '\n'; + } + llvm::errs() << "Use '" << argv0 + << " --help' for a complete list of options.\n"; + return 1; } - if (auto exit_code = InitializeReproducer(input_args)) { + if (auto exit_code = InitializeReproducer(argv[0], input_args)) { return *exit_code; } - // Register the reproducer signal handler. - llvm::sys::AddSignalHandler(reproducer_handler, const_cast<char *>(argv[0])); - SBError error = SBDebugger::InitializeWithErrorHandling(); if (error.Fail()) { WithColor::error() << "initialization failed: " << error.GetCString() |