diff options
Diffstat (limited to 'lldb/source/Commands/CommandObjectProcess.cpp')
-rw-r--r-- | lldb/source/Commands/CommandObjectProcess.cpp | 184 |
1 files changed, 141 insertions, 43 deletions
diff --git a/lldb/source/Commands/CommandObjectProcess.cpp b/lldb/source/Commands/CommandObjectProcess.cpp index d825647728f8..f86779d85b5f 100644 --- a/lldb/source/Commands/CommandObjectProcess.cpp +++ b/lldb/source/Commands/CommandObjectProcess.cpp @@ -1,4 +1,4 @@ -//===-- CommandObjectProcess.cpp --------------------------------*- C++ -*-===// +//===-- CommandObjectProcess.cpp ------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -13,7 +13,6 @@ #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" #include "lldb/Host/OptionParser.h" -#include "lldb/Host/StringConvert.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" #include "lldb/Interpreter/OptionArgParser.h" @@ -249,7 +248,6 @@ protected: return result.Succeeded(); } -protected: ProcessLaunchCommandOptions m_options; }; @@ -325,34 +323,38 @@ public: int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos; int opt_defs_index = opt_element_vector[opt_element_index].opt_defs_index; - // We are only completing the name option for now... - - // Are we in the name? - if (GetDefinitions()[opt_defs_index].short_option != 'n') - return; - - // Look to see if there is a -P argument provided, and if so use that - // plugin, otherwise use the default plugin. - - const char *partial_name = nullptr; - partial_name = request.GetParsedLine().GetArgumentAtIndex(opt_arg_pos); + switch (GetDefinitions()[opt_defs_index].short_option) { + case 'n': { + // Look to see if there is a -P argument provided, and if so use that + // plugin, otherwise use the default plugin. + + const char *partial_name = nullptr; + partial_name = request.GetParsedLine().GetArgumentAtIndex(opt_arg_pos); + + PlatformSP platform_sp(interpreter.GetPlatform(true)); + if (!platform_sp) + return; + ProcessInstanceInfoList process_infos; + ProcessInstanceInfoMatch match_info; + if (partial_name) { + match_info.GetProcessInfo().GetExecutableFile().SetFile( + partial_name, FileSpec::Style::native); + match_info.SetNameMatchType(NameMatch::StartsWith); + } + platform_sp->FindProcesses(match_info, process_infos); + const size_t num_matches = process_infos.size(); + if (num_matches == 0) + return; + for (size_t i = 0; i < num_matches; ++i) { + request.AddCompletion(process_infos[i].GetNameAsStringRef()); + } + } break; - PlatformSP platform_sp(interpreter.GetPlatform(true)); - if (!platform_sp) - return; - ProcessInstanceInfoList process_infos; - ProcessInstanceInfoMatch match_info; - if (partial_name) { - match_info.GetProcessInfo().GetExecutableFile().SetFile( - partial_name, FileSpec::Style::native); - match_info.SetNameMatchType(NameMatch::StartsWith); - } - platform_sp->FindProcesses(match_info, process_infos); - const size_t num_matches = process_infos.GetSize(); - if (num_matches == 0) - return; - for (size_t i = 0; i < num_matches; ++i) { - request.AddCompletion(process_infos.GetProcessNameAtIndex(i)); + case 'P': + CommandCompletions::InvokeCommonCompletionCallbacks( + interpreter, CommandCompletions::eProcessPluginCompletion, request, + nullptr); + break; } } @@ -759,7 +761,7 @@ public: switch (short_option) { case 'p': - plugin_name.assign(option_arg); + plugin_name.assign(std::string(option_arg)); break; default: @@ -818,9 +820,15 @@ protected: Status error; Debugger &debugger = GetDebugger(); PlatformSP platform_sp = m_interpreter.GetPlatform(true); - ProcessSP process_sp = platform_sp->ConnectProcess( - command.GetArgumentAtIndex(0), plugin_name, debugger, - debugger.GetSelectedTarget().get(), error); + ProcessSP process_sp = + debugger.GetAsyncExecution() + ? platform_sp->ConnectProcess( + command.GetArgumentAtIndex(0), plugin_name, debugger, + debugger.GetSelectedTarget().get(), error) + : platform_sp->ConnectProcessSynchronous( + command.GetArgumentAtIndex(0), plugin_name, debugger, + result.GetOutputStream(), debugger.GetSelectedTarget().get(), + error); if (error.Fail() || process_sp == nullptr) { result.AppendError(error.AsCString("Error connecting to the process")); result.SetStatus(eReturnStatusFailed); @@ -1034,6 +1042,20 @@ public: ~CommandObjectProcessSignal() override = default; + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { + if (!m_exe_ctx.HasProcessScope() || request.GetCursorIndex() != 0) + return; + + UnixSignalsSP signals = m_exe_ctx.GetProcessPtr()->GetUnixSignals(); + int signo = signals->GetFirstSignalNumber(); + while (signo != LLDB_INVALID_SIGNAL_NUMBER) { + request.AddCompletion(signals->GetSignalAsCString(signo), ""); + signo = signals->GetNextSignalNumber(signo); + } + } + protected: bool DoExecute(Args &command, CommandReturnObject &result) override { Process *process = m_exe_ctx.GetProcessPtr(); @@ -1042,10 +1064,10 @@ protected: int signo = LLDB_INVALID_SIGNAL_NUMBER; const char *signal_name = command.GetArgumentAtIndex(0); - if (::isxdigit(signal_name[0])) - signo = - StringConvert::ToSInt32(signal_name, LLDB_INVALID_SIGNAL_NUMBER, 0); - else + if (::isxdigit(signal_name[0])) { + if (!llvm::to_integer(signal_name, signo)) + signo = LLDB_INVALID_SIGNAL_NUMBER; + } else signo = process->GetUnixSignals()->GetSignalNumberFromName(signal_name); if (signo == LLDB_INVALID_SIGNAL_NUMBER) { @@ -1201,6 +1223,8 @@ protected: // CommandObjectProcessStatus #pragma mark CommandObjectProcessStatus +#define LLDB_OPTIONS_process_status +#include "CommandOptions.inc" class CommandObjectProcessStatus : public CommandObjectParsed { public: @@ -1209,13 +1233,57 @@ public: interpreter, "process status", "Show status and stop location for the current target process.", "process status", - eCommandRequiresProcess | eCommandTryTargetAPILock) {} + eCommandRequiresProcess | eCommandTryTargetAPILock), + m_options() {} ~CommandObjectProcessStatus() override = default; + Options *GetOptions() override { return &m_options; } + + class CommandOptions : public Options { + public: + CommandOptions() : Options(), m_verbose(false) {} + + ~CommandOptions() override = default; + + Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, + ExecutionContext *execution_context) override { + const int short_option = m_getopt_table[option_idx].val; + + switch (short_option) { + case 'v': + m_verbose = true; + break; + default: + llvm_unreachable("Unimplemented option"); + } + + return {}; + } + + void OptionParsingStarting(ExecutionContext *execution_context) override { + m_verbose = false; + } + + llvm::ArrayRef<OptionDefinition> GetDefinitions() override { + return llvm::makeArrayRef(g_process_status_options); + } + + // Instance variables to hold the values for command options. + bool m_verbose; + }; + +protected: bool DoExecute(Args &command, CommandReturnObject &result) override { Stream &strm = result.GetOutputStream(); result.SetStatus(eReturnStatusSuccessFinishNoResult); + + if (command.GetArgumentCount()) { + result.AppendError("'process status' takes no arguments"); + result.SetStatus(eReturnStatusFailed); + return result.Succeeded(); + } + // No need to check "process" for validity as eCommandRequiresProcess // ensures it is valid Process *process = m_exe_ctx.GetProcessPtr(); @@ -1227,8 +1295,37 @@ public: process->GetStatus(strm); process->GetThreadStatus(strm, only_threads_with_stop_reason, start_frame, num_frames, num_frames_with_source, stop_format); + + if (m_options.m_verbose) { + PlatformSP platform_sp = process->GetTarget().GetPlatform(); + if (!platform_sp) { + result.AppendError("Couldn'retrieve the target's platform"); + result.SetStatus(eReturnStatusFailed); + return result.Succeeded(); + } + + auto expected_crash_info = + platform_sp->FetchExtendedCrashInformation(*process); + + if (!expected_crash_info) { + result.AppendError(llvm::toString(expected_crash_info.takeError())); + result.SetStatus(eReturnStatusFailed); + return result.Succeeded(); + } + + StructuredData::DictionarySP crash_info_sp = *expected_crash_info; + + if (crash_info_sp) { + strm.PutCString("Extended Crash Information:\n"); + crash_info_sp->Dump(strm); + } + } + return result.Succeeded(); } + +private: + CommandOptions m_options; }; // CommandObjectProcessHandle @@ -1252,13 +1349,13 @@ public: switch (short_option) { case 's': - stop = option_arg; + stop = std::string(option_arg); break; case 'n': - notify = option_arg; + notify = std::string(option_arg); break; case 'p': - pass = option_arg; + pass = std::string(option_arg); break; default: llvm_unreachable("Unimplemented option"); @@ -1318,7 +1415,8 @@ public: real_value = 0; else { // If the value isn't 'true' or 'false', it had better be 0 or 1. - real_value = StringConvert::ToUInt32(option.c_str(), 3); + if (!llvm::to_integer(option, real_value)) + real_value = 3; if (real_value != 0 && real_value != 1) okay = false; } |