diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2022-03-20 11:40:34 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2022-05-14 11:43:05 +0000 |
commit | 349cc55c9796c4596a5b9904cd3281af295f878f (patch) | |
tree | 410c5a785075730a35f1272ca6a7adf72222ad03 /contrib/llvm-project/lldb/source/Commands/CommandObjectProcess.cpp | |
parent | cb2ae6163174b90e999326ecec3699ee093a5d43 (diff) | |
parent | c0981da47d5696fe36474fcf86b4ce03ae3ff818 (diff) |
Diffstat (limited to 'contrib/llvm-project/lldb/source/Commands/CommandObjectProcess.cpp')
-rw-r--r-- | contrib/llvm-project/lldb/source/Commands/CommandObjectProcess.cpp | 166 |
1 files changed, 139 insertions, 27 deletions
diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectProcess.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectProcess.cpp index 7aaba3731500..5fd1718e8484 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectProcess.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectProcess.cpp @@ -159,7 +159,12 @@ protected: // If our listener is nullptr, users aren't allows to launch ModuleSP exe_module_sp = target->GetExecutableModule(); - if (exe_module_sp == nullptr) { + // If the target already has an executable module, then use that. If it + // doesn't then someone must be trying to launch using a path that will + // make sense to the remote stub, but doesn't exist on the local host. + // In that case use the ExecutableFile that was set in the target's + // ProcessLaunchInfo. + if (exe_module_sp == nullptr && !target->GetProcessLaunchInfo().GetExecutableFile()) { result.AppendError("no file in target, create a debug target using the " "'target create' command"); return false; @@ -170,8 +175,6 @@ protected: if (!StopProcessIfNecessary(m_exe_ctx.GetProcessPtr(), state, result)) return false; - llvm::StringRef target_settings_argv0 = target->GetArg0(); - // Determine whether we will disable ASLR or leave it in the default state // (i.e. enabled if the platform supports it). First check if the process // launch options explicitly turn on/off @@ -216,14 +219,22 @@ protected: m_options.launch_info.GetEnvironment().insert(target_env.begin(), target_env.end()); + llvm::StringRef target_settings_argv0 = target->GetArg0(); + if (!target_settings_argv0.empty()) { m_options.launch_info.GetArguments().AppendArgument( target_settings_argv0); - m_options.launch_info.SetExecutableFile( - exe_module_sp->GetPlatformFileSpec(), false); + if (exe_module_sp) + m_options.launch_info.SetExecutableFile( + exe_module_sp->GetPlatformFileSpec(), false); + else + m_options.launch_info.SetExecutableFile(target->GetProcessLaunchInfo().GetExecutableFile(), false); } else { - m_options.launch_info.SetExecutableFile( - exe_module_sp->GetPlatformFileSpec(), true); + if (exe_module_sp) + m_options.launch_info.SetExecutableFile( + exe_module_sp->GetPlatformFileSpec(), true); + else + m_options.launch_info.SetExecutableFile(target->GetProcessLaunchInfo().GetExecutableFile(), true); } if (launch_args.GetArgumentCount() == 0) { @@ -250,11 +261,20 @@ protected: llvm::StringRef data = stream.GetString(); if (!data.empty()) result.AppendMessage(data); - const char *archname = - exe_module_sp->GetArchitecture().GetArchitectureName(); - result.AppendMessageWithFormat( - "Process %" PRIu64 " launched: '%s' (%s)\n", process_sp->GetID(), - exe_module_sp->GetFileSpec().GetPath().c_str(), archname); + // If we didn't have a local executable, then we wouldn't have had an + // executable module before launch. + if (!exe_module_sp) + exe_module_sp = target->GetExecutableModule(); + if (!exe_module_sp) { + result.AppendWarning("Could not get executable module after launch."); + } else { + + const char *archname = + exe_module_sp->GetArchitecture().GetArchitectureName(); + result.AppendMessageWithFormat( + "Process %" PRIu64 " launched: '%s' (%s)\n", process_sp->GetID(), + exe_module_sp->GetFileSpec().GetPath().c_str(), archname); + } result.SetStatus(eReturnStatusSuccessFinishResult); result.SetDidChangeProcessState(true); } else { @@ -398,9 +418,10 @@ protected: } StreamString stream; + ProcessSP process_sp; const auto error = target->Attach(m_options.attach_info, &stream); if (error.Success()) { - ProcessSP process_sp(target->GetProcessSP()); + process_sp = target->GetProcessSP(); if (process_sp) { result.AppendMessage(stream.GetString()); result.SetStatus(eReturnStatusSuccessFinishNoResult); @@ -452,8 +473,13 @@ protected: // This supports the use-case scenario of immediately continuing the // process once attached. - if (m_options.attach_info.GetContinueOnceAttached()) - m_interpreter.HandleCommand("process continue", eLazyBoolNo, result); + if (m_options.attach_info.GetContinueOnceAttached()) { + // We have made a process but haven't told the interpreter about it yet, + // so CheckRequirements will fail for "process continue". Set the override + // here: + ExecutionContext exe_ctx(process_sp); + m_interpreter.HandleCommand("process continue", eLazyBoolNo, exe_ctx, result); + } return result.Succeeded(); } @@ -1166,7 +1192,9 @@ protected: static constexpr OptionEnumValueElement g_corefile_save_style[] = { {eSaveCoreFull, "full", "Create a core file with all memory saved"}, {eSaveCoreDirtyOnly, "modified-memory", - "Create a corefile with only modified memory saved"}}; + "Create a corefile with only modified memory saved"}, + {eSaveCoreStackOnly, "stack", + "Create a corefile with only stack memory saved"}}; static constexpr OptionEnumValues SaveCoreStyles() { return OptionEnumValues(g_corefile_save_style); @@ -1178,12 +1206,13 @@ static constexpr OptionEnumValues SaveCoreStyles() { class CommandObjectProcessSaveCore : public CommandObjectParsed { public: CommandObjectProcessSaveCore(CommandInterpreter &interpreter) - : CommandObjectParsed(interpreter, "process save-core", - "Save the current process as a core file using an " - "appropriate file type.", - "process save-core [-s corefile-style] FILE", - eCommandRequiresProcess | eCommandTryTargetAPILock | - eCommandProcessMustBeLaunched) {} + : CommandObjectParsed( + interpreter, "process save-core", + "Save the current process as a core file using an " + "appropriate file type.", + "process save-core [-s corefile-style -p plugin-name] FILE", + eCommandRequiresProcess | eCommandTryTargetAPILock | + eCommandProcessMustBeLaunched) {} ~CommandObjectProcessSaveCore() override = default; @@ -1206,6 +1235,9 @@ public: Status error; switch (short_option) { + case 'p': + m_requested_plugin_name = option_arg.str(); + break; case 's': m_requested_save_core_style = (lldb::SaveCoreStyle)OptionArgParser::ToOptionEnum( @@ -1221,10 +1253,12 @@ public: void OptionParsingStarting(ExecutionContext *execution_context) override { m_requested_save_core_style = eSaveCoreUnspecified; + m_requested_plugin_name.clear(); } // Instance variables to hold the values for command options. SaveCoreStyle m_requested_save_core_style; + std::string m_requested_plugin_name; }; protected: @@ -1235,13 +1269,15 @@ protected: FileSpec output_file(command.GetArgumentAtIndex(0)); SaveCoreStyle corefile_style = m_options.m_requested_save_core_style; Status error = - PluginManager::SaveCore(process_sp, output_file, corefile_style); + PluginManager::SaveCore(process_sp, output_file, corefile_style, + m_options.m_requested_plugin_name); if (error.Success()) { - if (corefile_style == SaveCoreStyle::eSaveCoreDirtyOnly) { + if (corefile_style == SaveCoreStyle::eSaveCoreDirtyOnly || + corefile_style == SaveCoreStyle::eSaveCoreStackOnly) { result.AppendMessageWithFormat( - "\nModified-memory only corefile " - "created. This corefile may not show \n" - "library/framework/app binaries " + "\nModified-memory or stack-memory only corefile " + "created. This corefile may \n" + "not show library/framework/app binaries " "on a different system, or when \n" "those binaries have " "been updated/modified. Copies are not included\n" @@ -1641,6 +1677,80 @@ protected: } }; +// CommandObjectProcessTraceSave +#define LLDB_OPTIONS_process_trace_save +#include "CommandOptions.inc" + +#pragma mark CommandObjectProcessTraceSave + +class CommandObjectProcessTraceSave : public CommandObjectParsed { +public: + class CommandOptions : public Options { + public: + CommandOptions() : Options() { OptionParsingStarting(nullptr); } + + Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, + ExecutionContext *execution_context) override { + Status error; + const int short_option = m_getopt_table[option_idx].val; + + switch (short_option) { + + case 'd': { + m_directory.SetFile(option_arg, FileSpec::Style::native); + FileSystem::Instance().Resolve(m_directory); + break; + } + default: + llvm_unreachable("Unimplemented option"); + } + return error; + } + + void OptionParsingStarting(ExecutionContext *execution_context) override{}; + + llvm::ArrayRef<OptionDefinition> GetDefinitions() override { + return llvm::makeArrayRef(g_process_trace_save_options); + }; + + FileSpec m_directory; + }; + + Options *GetOptions() override { return &m_options; } + CommandObjectProcessTraceSave(CommandInterpreter &interpreter) + : CommandObjectParsed( + interpreter, "process trace save", + "Save the trace of the current process in the specified directory. " + "The directory will be created if needed. " + "This will also create a file <directory>/trace.json with the main " + "properties of the trace session, along with others files which " + "contain the actual trace data. The trace.json file can be used " + "later as input for the \"trace load\" command to load the trace " + "in LLDB", + "process trace save [<cmd-options>]", + eCommandRequiresProcess | eCommandTryTargetAPILock | + eCommandProcessMustBeLaunched | eCommandProcessMustBePaused | + eCommandProcessMustBeTraced) {} + + ~CommandObjectProcessTraceSave() override = default; + +protected: + bool DoExecute(Args &command, CommandReturnObject &result) override { + ProcessSP process_sp = m_exe_ctx.GetProcessSP(); + + TraceSP trace_sp = process_sp->GetTarget().GetTrace(); + + if (llvm::Error err = trace_sp->SaveLiveTraceToDisk(m_options.m_directory)) + result.AppendError(toString(std::move(err))); + else + result.SetStatus(eReturnStatusSuccessFinishResult); + + return result.Succeeded(); + } + + CommandOptions m_options; +}; + // CommandObjectProcessTraceStop class CommandObjectProcessTraceStop : public CommandObjectParsed { public: @@ -1678,6 +1788,8 @@ public: : CommandObjectMultiword( interpreter, "trace", "Commands for tracing the current process.", "process trace <subcommand> [<subcommand objects>]") { + LoadSubCommand("save", CommandObjectSP( + new CommandObjectProcessTraceSave(interpreter))); LoadSubCommand("start", CommandObjectSP(new CommandObjectProcessTraceStart( interpreter))); LoadSubCommand("stop", CommandObjectSP( |