summaryrefslogtreecommitdiff
path: root/gnu/llvm/lldb
diff options
context:
space:
mode:
authorJonathan Gray <jsg@cvs.openbsd.org>2021-05-01 00:43:13 +0000
committerJonathan Gray <jsg@cvs.openbsd.org>2021-05-01 00:43:13 +0000
commit9f72b64eaacefae0bd746ca3158e1b34b8be6c48 (patch)
tree829990b735eb8496e3c82e988ddc256af054c7dc /gnu/llvm/lldb
parentc9c613255725ec9c225e463b0b2af0daaafbd8e8 (diff)
arvm7 -> armv7
Diffstat (limited to 'gnu/llvm/lldb')
-rw-r--r--gnu/llvm/lldb/docs/man/lldb.rst22
-rw-r--r--gnu/llvm/lldb/tools/driver/Driver.cpp180
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()