diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2023-12-09 13:28:42 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2023-12-09 13:28:42 +0000 |
| commit | b1c73532ee8997fe5dfbeb7d223027bdf99758a0 (patch) | |
| tree | 7d6e51c294ab6719475d660217aa0c0ad0526292 /lldb/source/Commands/CommandObjectTarget.cpp | |
| parent | 7fa27ce4a07f19b07799a767fc29416f3b625afb (diff) | |
Diffstat (limited to 'lldb/source/Commands/CommandObjectTarget.cpp')
| -rw-r--r-- | lldb/source/Commands/CommandObjectTarget.cpp | 515 |
1 files changed, 378 insertions, 137 deletions
diff --git a/lldb/source/Commands/CommandObjectTarget.cpp b/lldb/source/Commands/CommandObjectTarget.cpp index 3e024ff91b38..63232c221ad1 100644 --- a/lldb/source/Commands/CommandObjectTarget.cpp +++ b/lldb/source/Commands/CommandObjectTarget.cpp @@ -8,10 +8,12 @@ #include "CommandObjectTarget.h" +#include "lldb/Core/Address.h" #include "lldb/Core/Debugger.h" #include "lldb/Core/IOHandler.h" #include "lldb/Core/Module.h" #include "lldb/Core/ModuleSpec.h" +#include "lldb/Core/PluginManager.h" #include "lldb/Core/Section.h" #include "lldb/Core/ValueObjectVariable.h" #include "lldb/DataFormatters/ValueObjectPrinter.h" @@ -35,7 +37,6 @@ #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/FuncUnwinders.h" #include "lldb/Symbol/LineTable.h" -#include "lldb/Symbol/LocateSymbolFile.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Symbol/SymbolFile.h" #include "lldb/Symbol/UnwindPlan.h" @@ -52,6 +53,7 @@ #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/State.h" +#include "lldb/Utility/StructuredData.h" #include "lldb/Utility/Timer.h" #include "lldb/lldb-enumerations.h" #include "lldb/lldb-private-enumerations.h" @@ -61,6 +63,7 @@ #include "clang/Frontend/CompilerInvocation.h" #include "clang/Frontend/FrontendActions.h" #include "llvm/ADT/ScopeExit.h" +#include "llvm/ADT/StringRef.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/FormatAdapters.h" @@ -261,7 +264,7 @@ public: } protected: - bool DoExecute(Args &command, CommandReturnObject &result) override { + void DoExecute(Args &command, CommandReturnObject &result) override { const size_t argc = command.GetArgumentCount(); FileSpec core_file(m_core_file.GetOptionValue().GetCurrentValue()); FileSpec remote_file(m_remote_file.GetOptionValue().GetCurrentValue()); @@ -274,7 +277,7 @@ protected: result.AppendErrorWithFormatv("Cannot open '{0}': {1}.", core_file.GetPath(), llvm::toString(file.takeError())); - return false; + return; } } @@ -288,7 +291,7 @@ protected: result.AppendErrorWithFormatv("Cannot open '{0}': {1}.", symfile.GetPath(), llvm::toString(file.takeError())); - return false; + return; } } @@ -308,7 +311,7 @@ protected: if (!target_sp) { result.AppendError(error.AsCString()); - return false; + return; } const llvm::StringRef label = @@ -316,7 +319,7 @@ protected: if (!label.empty()) { if (auto E = target_sp->SetLabel(label)) result.SetError(std::move(E)); - return false; + return; } auto on_error = llvm::make_scope_exit( @@ -351,7 +354,7 @@ protected: Status err = platform_sp->PutFile(file_spec, remote_file); if (err.Fail()) { result.AppendError(err.AsCString()); - return false; + return; } } } else { @@ -365,7 +368,7 @@ protected: Status err = platform_sp->GetFile(remote_file, file_spec); if (err.Fail()) { result.AppendError(err.AsCString()); - return false; + return; } } else { // If the remote file exists, we can debug reading that out of @@ -379,12 +382,12 @@ protected: if (platform_sp->IsHost()) { result.AppendError("Supply a local file, not a remote file, " "when debugging on the host."); - return false; + return; } if (platform_sp->IsConnected() && !platform_sp->GetFileExists(remote_file)) { result.AppendError("remote --> local transfer without local " "path is not implemented yet"); - return false; + return; } // Since there's only a remote file, we need to set the executable // file spec to the remote one. @@ -395,7 +398,7 @@ protected: } } else { result.AppendError("no platform found for target"); - return false; + return; } } @@ -434,9 +437,8 @@ protected: error = process_sp->LoadCore(); if (error.Fail()) { - result.AppendError( - error.AsCString("can't find plug-in for core file")); - return false; + result.AppendError(error.AsCString("unknown core file format")); + return; } else { result.AppendMessageWithFormatv( "Core file '{0}' ({1}) was loaded.\n", core_file.GetPath(), @@ -445,9 +447,8 @@ protected: on_error.release(); } } else { - result.AppendErrorWithFormatv( - "Unable to find process plug-in for core file '{0}'\n", - core_file.GetPath()); + result.AppendErrorWithFormatv("Unknown core file format '{0}'\n", + core_file.GetPath()); } } else { result.AppendMessageWithFormat( @@ -462,8 +463,6 @@ protected: "argument, or use the --core option.\n", m_cmd_name.c_str()); } - - return result.Succeeded(); } private: @@ -490,7 +489,7 @@ public: ~CommandObjectTargetList() override = default; protected: - bool DoExecute(Args &args, CommandReturnObject &result) override { + void DoExecute(Args &args, CommandReturnObject &result) override { Stream &strm = result.GetOutputStream(); bool show_stopped_process_status = false; @@ -499,7 +498,6 @@ protected: strm.PutCString("No targets.\n"); } result.SetStatus(eReturnStatusSuccessFinishResult); - return result.Succeeded(); } }; @@ -518,7 +516,7 @@ public: ~CommandObjectTargetSelect() override = default; protected: - bool DoExecute(Args &args, CommandReturnObject &result) override { + void DoExecute(Args &args, CommandReturnObject &result) override { if (args.GetArgumentCount() == 1) { const char *target_identifier = args.GetArgumentAtIndex(0); uint32_t target_idx = LLDB_INVALID_INDEX32; @@ -568,7 +566,6 @@ protected: result.AppendError( "'target select' takes a single argument: a target index\n"); } - return result.Succeeded(); } }; @@ -604,7 +601,7 @@ public: Options *GetOptions() override { return &m_option_group; } protected: - bool DoExecute(Args &args, CommandReturnObject &result) override { + void DoExecute(Args &args, CommandReturnObject &result) override { const size_t argc = args.GetArgumentCount(); std::vector<TargetSP> delete_target_list; TargetList &target_list = GetDebugger().GetTargetList(); @@ -618,7 +615,7 @@ protected: // Bail out if don't have any targets. if (num_targets == 0) { result.AppendError("no targets to delete"); - return false; + return; } for (auto &entry : args.entries()) { @@ -626,7 +623,7 @@ protected: if (entry.ref().getAsInteger(0, target_idx)) { result.AppendErrorWithFormat("invalid target index '%s'\n", entry.c_str()); - return false; + return; } if (target_idx < num_targets) { target_sp = target_list.GetTargetAtIndex(target_idx); @@ -644,13 +641,13 @@ protected: "target index %u is out of range, the only valid index is 0\n", target_idx); - return false; + return; } } else { target_sp = target_list.GetSelectedTarget(); if (!target_sp) { result.AppendErrorWithFormat("no target is currently selected\n"); - return false; + return; } delete_target_list.push_back(target_sp); } @@ -671,7 +668,7 @@ protected: (uint32_t)num_targets_to_delete); result.SetStatus(eReturnStatusSuccessFinishResult); - return true; + return; } OptionGroupOptions m_option_group; @@ -692,7 +689,7 @@ public: ~CommandObjectTargetShowLaunchEnvironment() override = default; protected: - bool DoExecute(Args &args, CommandReturnObject &result) override { + void DoExecute(Args &args, CommandReturnObject &result) override { Target *target = m_exe_ctx.GetTargetPtr(); Environment env = target->GetEnvironment(); @@ -710,7 +707,6 @@ protected: strm.Format("{0}={1}\n", KV->first(), KV->second); result.SetStatus(eReturnStatusSuccessFinishResult); - return result.Succeeded(); } }; @@ -863,7 +859,7 @@ protected: } } - bool DoExecute(Args &args, CommandReturnObject &result) override { + void DoExecute(Args &args, CommandReturnObject &result) override { Target *target = m_exe_ctx.GetTargetPtr(); const size_t argc = args.GetArgumentCount(); Stream &s = result.GetOutputStream(); @@ -880,7 +876,7 @@ protected: if (!regex.IsValid()) { result.GetErrorStream().Printf( "error: invalid regular expression: '%s'\n", arg.c_str()); - return false; + return; } use_var_name = true; target->GetImages().FindGlobalVariables(regex, UINT32_MAX, @@ -896,7 +892,7 @@ protected: if (matches == 0) { result.AppendErrorWithFormat("can't find global variable '%s'", arg.c_str()); - return false; + return; } else { for (uint32_t global_idx = 0; global_idx < matches; ++global_idx) { VariableSP var_sp(variable_list.GetVariableAtIndex(global_idx)); @@ -1014,8 +1010,6 @@ protected: m_interpreter.PrintWarningsIfNecessary(result.GetOutputStream(), m_cmd_name); - - return result.Succeeded(); } OptionGroupOptions m_option_group; @@ -1062,7 +1056,7 @@ public: ~CommandObjectTargetModulesSearchPathsAdd() override = default; protected: - bool DoExecute(Args &command, CommandReturnObject &result) override { + void DoExecute(Args &command, CommandReturnObject &result) override { Target *target = &GetSelectedTarget(); const size_t argc = command.GetArgumentCount(); if (argc & 1) { @@ -1092,7 +1086,6 @@ protected: } } } - return result.Succeeded(); } }; @@ -1110,12 +1103,11 @@ public: ~CommandObjectTargetModulesSearchPathsClear() override = default; protected: - bool DoExecute(Args &command, CommandReturnObject &result) override { + void DoExecute(Args &command, CommandReturnObject &result) override { Target *target = &GetSelectedTarget(); bool notify = true; target->GetImageSearchPathList().Clear(notify); result.SetStatus(eReturnStatusSuccessFinishNoResult); - return result.Succeeded(); } }; @@ -1185,7 +1177,7 @@ public: } protected: - bool DoExecute(Args &command, CommandReturnObject &result) override { + void DoExecute(Args &command, CommandReturnObject &result) override { Target *target = &GetSelectedTarget(); size_t argc = command.GetArgumentCount(); // check for at least 3 arguments and an odd number of parameters @@ -1196,7 +1188,7 @@ protected: result.AppendErrorWithFormat( "<index> parameter is not an integer: '%s'.\n", command.GetArgumentAtIndex(0)); - return result.Succeeded(); + return; } // shift off the index @@ -1217,14 +1209,12 @@ protected: result.AppendError("<path-prefix> can't be empty\n"); else result.AppendError("<new-path-prefix> can't be empty\n"); - return false; + return; } } } else { result.AppendError("insert requires at least three arguments\n"); - return result.Succeeded(); } - return result.Succeeded(); } }; @@ -1242,12 +1232,11 @@ public: ~CommandObjectTargetModulesSearchPathsList() override = default; protected: - bool DoExecute(Args &command, CommandReturnObject &result) override { + void DoExecute(Args &command, CommandReturnObject &result) override { Target *target = &GetSelectedTarget(); target->GetImageSearchPathList().Dump(&result.GetOutputStream()); result.SetStatus(eReturnStatusSuccessFinishResult); - return result.Succeeded(); } }; @@ -1278,11 +1267,11 @@ public: ~CommandObjectTargetModulesSearchPathsQuery() override = default; protected: - bool DoExecute(Args &command, CommandReturnObject &result) override { + void DoExecute(Args &command, CommandReturnObject &result) override { Target *target = &GetSelectedTarget(); if (command.GetArgumentCount() != 1) { result.AppendError("query requires one argument\n"); - return result.Succeeded(); + return; } ConstString orig(command.GetArgumentAtIndex(0)); @@ -1293,7 +1282,6 @@ protected: result.GetOutputStream().Printf("%s\n", orig.GetCString()); result.SetStatus(eReturnStatusSuccessFinishResult); - return result.Succeeded(); } }; @@ -1462,9 +1450,90 @@ static bool DumpModuleSymbolFile(Stream &strm, Module *module) { return false; } +static bool GetSeparateDebugInfoList(StructuredData::Array &list, + Module *module, bool errors_only) { + if (module) { + if (SymbolFile *symbol_file = module->GetSymbolFile(/*can_create=*/true)) { + StructuredData::Dictionary d; + if (symbol_file->GetSeparateDebugInfo(d, errors_only)) { + list.AddItem( + std::make_shared<StructuredData::Dictionary>(std::move(d))); + return true; + } + } + } + return false; +} + +static void DumpDwoFilesTable(Stream &strm, + StructuredData::Array &dwo_listings) { + strm.PutCString("Dwo ID Err Dwo Path"); + strm.EOL(); + strm.PutCString( + "------------------ --- -----------------------------------------"); + strm.EOL(); + dwo_listings.ForEach([&strm](StructuredData::Object *dwo) { + StructuredData::Dictionary *dict = dwo->GetAsDictionary(); + if (!dict) + return false; + + uint64_t dwo_id; + if (dict->GetValueForKeyAsInteger("dwo_id", dwo_id)) + strm.Printf("0x%16.16" PRIx64 " ", dwo_id); + else + strm.Printf("0x???????????????? "); + + llvm::StringRef error; + if (dict->GetValueForKeyAsString("error", error)) + strm << "E " << error; + else { + llvm::StringRef resolved_dwo_path; + if (dict->GetValueForKeyAsString("resolved_dwo_path", + resolved_dwo_path)) { + strm << " " << resolved_dwo_path; + if (resolved_dwo_path.ends_with(".dwp")) { + llvm::StringRef dwo_name; + if (dict->GetValueForKeyAsString("dwo_name", dwo_name)) + strm << "(" << dwo_name << ")"; + } + } + } + strm.EOL(); + return true; + }); +} + +static void DumpOsoFilesTable(Stream &strm, + StructuredData::Array &oso_listings) { + strm.PutCString("Mod Time Err Oso Path"); + strm.EOL(); + strm.PutCString("------------------ --- ---------------------"); + strm.EOL(); + oso_listings.ForEach([&strm](StructuredData::Object *oso) { + StructuredData::Dictionary *dict = oso->GetAsDictionary(); + if (!dict) + return false; + + uint32_t oso_mod_time; + if (dict->GetValueForKeyAsInteger("oso_mod_time", oso_mod_time)) + strm.Printf("0x%16.16" PRIx32 " ", oso_mod_time); + + llvm::StringRef error; + if (dict->GetValueForKeyAsString("error", error)) + strm << "E " << error; + else { + llvm::StringRef oso_path; + if (dict->GetValueForKeyAsString("oso_path", oso_path)) + strm << " " << oso_path; + } + strm.EOL(); + return true; + }); +} + static void DumpAddress(ExecutionContextScope *exe_scope, const Address &so_addr, bool verbose, bool all_ranges, - Stream &strm) { + Stream &strm, llvm::StringRef pattern = "") { strm.IndentMore(); strm.Indent(" Address: "); so_addr.Dump(&strm, exe_scope, Address::DumpStyleModuleWithFileAddress); @@ -1474,13 +1543,14 @@ static void DumpAddress(ExecutionContextScope *exe_scope, strm.Indent(" Summary: "); const uint32_t save_indent = strm.GetIndentLevel(); strm.SetIndentLevel(save_indent + 13); - so_addr.Dump(&strm, exe_scope, Address::DumpStyleResolvedDescription); + so_addr.Dump(&strm, exe_scope, Address::DumpStyleResolvedDescription, + Address::DumpStyleInvalid, UINT32_MAX, false, pattern); strm.SetIndentLevel(save_indent); // Print out detailed address information when verbose is enabled if (verbose) { strm.EOL(); so_addr.Dump(&strm, exe_scope, Address::DumpStyleDetailedSymbolContext, - Address::DumpStyleInvalid, UINT32_MAX, all_ranges); + Address::DumpStyleInvalid, UINT32_MAX, all_ranges, pattern); } strm.IndentLess(); } @@ -1525,6 +1595,7 @@ static uint32_t LookupSymbolInModule(CommandInterpreter &interpreter, return 0; SymbolContext sc; + const bool use_color = interpreter.GetDebugger().GetUseColor(); std::vector<uint32_t> match_indexes; ConstString symbol_name(name); uint32_t num_matches = 0; @@ -1550,12 +1621,19 @@ static uint32_t LookupSymbolInModule(CommandInterpreter &interpreter, if (symbol->ValueIsAddress()) { DumpAddress( interpreter.GetExecutionContext().GetBestExecutionContextScope(), - symbol->GetAddressRef(), verbose, all_ranges, strm); + symbol->GetAddressRef(), verbose, all_ranges, strm, + use_color && name_is_regex ? name : nullptr); strm.EOL(); } else { strm.IndentMore(); strm.Indent(" Name: "); - strm.PutCString(symbol->GetDisplayName().GetStringRef()); + llvm::StringRef ansi_prefix = + interpreter.GetDebugger().GetRegexMatchAnsiPrefix(); + llvm::StringRef ansi_suffix = + interpreter.GetDebugger().GetRegexMatchAnsiSuffix(); + strm.PutCStringColorHighlighted( + symbol->GetDisplayName().GetStringRef(), + use_color ? name : nullptr, ansi_prefix, ansi_suffix); strm.EOL(); strm.Indent(" Value: "); strm.Printf("0x%16.16" PRIx64 "\n", symbol->GetRawValue()); @@ -1879,7 +1957,7 @@ public: ~CommandObjectTargetModulesDumpObjfile() override = default; protected: - bool DoExecute(Args &command, CommandReturnObject &result) override { + void DoExecute(Args &command, CommandReturnObject &result) override { Target *target = &GetSelectedTarget(); uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); @@ -1918,7 +1996,6 @@ protected: } else { result.AppendError("no matching executable images found"); } - return result.Succeeded(); } }; @@ -1981,7 +2058,7 @@ public: }; protected: - bool DoExecute(Args &command, CommandReturnObject &result) override { + void DoExecute(Args &command, CommandReturnObject &result) override { Target *target = &GetSelectedTarget(); uint32_t num_dumped = 0; Mangled::NamePreference name_preference = @@ -2017,7 +2094,7 @@ protected: } } else { result.AppendError("the target has no associated executable images"); - return false; + return; } } else { // Dump specified images (by basename or fullpath) @@ -2057,7 +2134,6 @@ protected: else { result.AppendError("no matching executable images found"); } - return result.Succeeded(); } CommandOptions m_options; @@ -2080,7 +2156,7 @@ public: ~CommandObjectTargetModulesDumpSections() override = default; protected: - bool DoExecute(Args &command, CommandReturnObject &result) override { + void DoExecute(Args &command, CommandReturnObject &result) override { Target *target = &GetSelectedTarget(); uint32_t num_dumped = 0; @@ -2093,7 +2169,7 @@ protected: const size_t num_modules = target->GetImages().GetSize(); if (num_modules == 0) { result.AppendError("the target has no associated executable images"); - return false; + return; } result.GetOutputStream().Format("Dumping sections for {0} modules.\n", @@ -2148,7 +2224,6 @@ protected: else { result.AppendError("no matching executable images found"); } - return result.Succeeded(); } }; @@ -2166,11 +2241,11 @@ public: ~CommandObjectTargetModulesDumpClangPCMInfo() override = default; protected: - bool DoExecute(Args &command, CommandReturnObject &result) override { + void DoExecute(Args &command, CommandReturnObject &result) override { if (command.GetArgumentCount() != 1) { result.AppendErrorWithFormat("'%s' takes exactly one pcm path argument.", m_cmd_name.c_str()); - return false; + return; } const char *pcm_path = command.GetArgumentAtIndex(0); @@ -2178,12 +2253,12 @@ protected: if (pcm_file.GetFileNameExtension() != ".pcm") { result.AppendError("file must have a .pcm extension"); - return false; + return; } if (!FileSystem::Instance().Exists(pcm_file)) { result.AppendError("pcm file does not exist"); - return false; + return; } clang::CompilerInstance compiler; @@ -2203,8 +2278,6 @@ protected: if (compiler.ExecuteAction(dump_module_info)) result.SetStatus(eReturnStatusSuccessFinishResult); - - return result.Succeeded(); } }; @@ -2225,14 +2298,14 @@ public: ~CommandObjectTargetModulesDumpClangAST() override = default; protected: - bool DoExecute(Args &command, CommandReturnObject &result) override { + void DoExecute(Args &command, CommandReturnObject &result) override { Target *target = &GetSelectedTarget(); const ModuleList &module_list = target->GetImages(); const size_t num_modules = module_list.GetSize(); if (num_modules == 0) { result.AppendError("the target has no associated executable images"); - return false; + return; } if (command.GetArgumentCount() == 0) { @@ -2246,7 +2319,7 @@ protected: sf->DumpClangAST(result.GetOutputStream()); } result.SetStatus(eReturnStatusSuccessFinishResult); - return true; + return; } // Dump specified ASTs (by basename or fullpath) @@ -2276,7 +2349,6 @@ protected: } } result.SetStatus(eReturnStatusSuccessFinishResult); - return true; } }; @@ -2297,7 +2369,7 @@ public: ~CommandObjectTargetModulesDumpSymfile() override = default; protected: - bool DoExecute(Args &command, CommandReturnObject &result) override { + void DoExecute(Args &command, CommandReturnObject &result) override { Target *target = &GetSelectedTarget(); uint32_t num_dumped = 0; @@ -2312,7 +2384,7 @@ protected: const size_t num_modules = target_modules.GetSize(); if (num_modules == 0) { result.AppendError("the target has no associated executable images"); - return false; + return; } result.GetOutputStream().Format( "Dumping debug symbols for {0} modules.\n", num_modules); @@ -2357,7 +2429,6 @@ protected: else { result.AppendError("no matching executable images found"); } - return result.Succeeded(); } }; @@ -2381,7 +2452,7 @@ public: Options *GetOptions() override { return &m_options; } protected: - bool DoExecute(Args &command, CommandReturnObject &result) override { + void DoExecute(Args &command, CommandReturnObject &result) override { Target *target = m_exe_ctx.GetTargetPtr(); uint32_t total_num_dumped = 0; @@ -2391,7 +2462,7 @@ protected: if (command.GetArgumentCount() == 0) { result.AppendError("file option must be specified."); - return result.Succeeded(); + return; } else { // Dump specified images (by basename or fullpath) const char *arg_cstr; @@ -2433,7 +2504,6 @@ protected: else { result.AppendError("no source filenames matched any command arguments"); } - return result.Succeeded(); } class CommandOptions : public Options { @@ -2462,6 +2532,185 @@ protected: CommandOptions m_options; }; +#pragma mark CommandObjectTargetModulesDumpSeparateDebugInfoFiles +#define LLDB_OPTIONS_target_modules_dump_separate_debug_info +#include "CommandOptions.inc" + +// Image debug separate debug info dumping command + +class CommandObjectTargetModulesDumpSeparateDebugInfoFiles + : public CommandObjectTargetModulesModuleAutoComplete { +public: + CommandObjectTargetModulesDumpSeparateDebugInfoFiles( + CommandInterpreter &interpreter) + : CommandObjectTargetModulesModuleAutoComplete( + interpreter, "target modules dump separate-debug-info", + "List the separate debug info symbol files for one or more target " + "modules.", + nullptr, eCommandRequiresTarget) {} + + ~CommandObjectTargetModulesDumpSeparateDebugInfoFiles() override = default; + + Options *GetOptions() override { return &m_options; } + + class CommandOptions : public Options { + public: + CommandOptions() = default; + + ~CommandOptions() override = default; + + 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 'j': + m_json.SetCurrentValue(true); + m_json.SetOptionWasSet(); + break; + case 'e': + m_errors_only.SetCurrentValue(true); + m_errors_only.SetOptionWasSet(); + break; + default: + llvm_unreachable("Unimplemented option"); + } + return error; + } + + void OptionParsingStarting(ExecutionContext *execution_context) override { + m_json.Clear(); + m_errors_only.Clear(); + } + + llvm::ArrayRef<OptionDefinition> GetDefinitions() override { + return llvm::ArrayRef(g_target_modules_dump_separate_debug_info_options); + } + + OptionValueBoolean m_json = false; + OptionValueBoolean m_errors_only = false; + }; + +protected: + void DoExecute(Args &command, CommandReturnObject &result) override { + Target &target = GetSelectedTarget(); + uint32_t num_dumped = 0; + + uint32_t addr_byte_size = target.GetArchitecture().GetAddressByteSize(); + result.GetOutputStream().SetAddressByteSize(addr_byte_size); + result.GetErrorStream().SetAddressByteSize(addr_byte_size); + + StructuredData::Array separate_debug_info_lists_by_module; + if (command.GetArgumentCount() == 0) { + // Dump all sections for all modules images + const ModuleList &target_modules = target.GetImages(); + std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex()); + const size_t num_modules = target_modules.GetSize(); + if (num_modules == 0) { + result.AppendError("the target has no associated executable images"); + return; + } + for (ModuleSP module_sp : target_modules.ModulesNoLocking()) { + if (INTERRUPT_REQUESTED( + GetDebugger(), + "Interrupted in dumping all " + "separate debug info with {0} of {1} modules dumped", + num_dumped, num_modules)) + break; + + if (GetSeparateDebugInfoList(separate_debug_info_lists_by_module, + module_sp.get(), + bool(m_options.m_errors_only))) + num_dumped++; + } + } else { + // Dump specified images (by basename or fullpath) + const char *arg_cstr; + for (int arg_idx = 0; + (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr; + ++arg_idx) { + ModuleList module_list; + const size_t num_matches = + FindModulesByName(&target, arg_cstr, module_list, true); + if (num_matches > 0) { + for (size_t i = 0; i < num_matches; ++i) { + if (INTERRUPT_REQUESTED(GetDebugger(), + "Interrupted dumping {0} " + "of {1} requested modules", + i, num_matches)) + break; + Module *module = module_list.GetModulePointerAtIndex(i); + if (GetSeparateDebugInfoList(separate_debug_info_lists_by_module, + module, bool(m_options.m_errors_only))) + num_dumped++; + } + } else + result.AppendWarningWithFormat( + "Unable to find an image that matches '%s'.\n", arg_cstr); + } + } + + if (num_dumped > 0) { + Stream &strm = result.GetOutputStream(); + // Display the debug info files in some format. + if (m_options.m_json) { + // JSON format + separate_debug_info_lists_by_module.Dump(strm, + /*pretty_print=*/true); + } else { + // Human-readable table format + separate_debug_info_lists_by_module.ForEach( + [&result, &strm](StructuredData::Object *obj) { + if (!obj) { + return false; + } + + // Each item in `separate_debug_info_lists_by_module` should be a + // valid structured data dictionary. + StructuredData::Dictionary *separate_debug_info_list = + obj->GetAsDictionary(); + if (!separate_debug_info_list) { + return false; + } + + llvm::StringRef type; + llvm::StringRef symfile; + StructuredData::Array *files; + if (!(separate_debug_info_list->GetValueForKeyAsString("type", + type) && + separate_debug_info_list->GetValueForKeyAsString("symfile", + symfile) && + separate_debug_info_list->GetValueForKeyAsArray( + "separate-debug-info-files", files))) { + assert(false); + } + + strm << "Symbol file: " << symfile; + strm.EOL(); + strm << "Type: \"" << type << "\""; + strm.EOL(); + if (type == "dwo") { + DumpDwoFilesTable(strm, *files); + } else if (type == "oso") { + DumpOsoFilesTable(strm, *files); + } else { + result.AppendWarningWithFormat( + "Found unsupported debug info type '%s'.\n", + type.str().c_str()); + } + return true; + }); + } + result.SetStatus(eReturnStatusSuccessFinishResult); + } else { + result.AppendError("no matching executable images found"); + } + } + + CommandOptions m_options; +}; + #pragma mark CommandObjectTargetModulesDump // Dump multi-word command for target modules @@ -2475,7 +2724,8 @@ public: "Commands for dumping information about one or more target " "modules.", "target modules dump " - "[objfile|symtab|sections|ast|symfile|line-table|pcm-info] " + "[objfile|symtab|sections|ast|symfile|line-table|pcm-info|separate-" + "debug-info] " "[<file1> <file2> ...]") { LoadSubCommand("objfile", CommandObjectSP( @@ -2499,6 +2749,10 @@ public: "pcm-info", CommandObjectSP( new CommandObjectTargetModulesDumpClangPCMInfo(interpreter))); + LoadSubCommand("separate-debug-info", + CommandObjectSP( + new CommandObjectTargetModulesDumpSeparateDebugInfoFiles( + interpreter))); } ~CommandObjectTargetModulesDump() override = default; @@ -2540,7 +2794,7 @@ protected: OptionGroupUUID m_uuid_option_group; OptionGroupFile m_symbol_file; - bool DoExecute(Args &args, CommandReturnObject &result) override { + void DoExecute(Args &args, CommandReturnObject &result) override { Target *target = &GetSelectedTarget(); bool flush = false; @@ -2555,12 +2809,12 @@ protected: module_spec.GetSymbolFileSpec() = m_symbol_file.GetOptionValue().GetCurrentValue(); Status error; - if (Symbols::DownloadObjectAndSymbolFile(module_spec, error)) { + if (PluginManager::DownloadObjectAndSymbolFile(module_spec, error)) { ModuleSP module_sp( target->GetOrCreateModule(module_spec, true /* notify */)); if (module_sp) { result.SetStatus(eReturnStatusSuccessFinishResult); - return true; + return; } else { StreamString strm; module_spec.GetUUID().Dump(strm); @@ -2583,7 +2837,7 @@ protected: "or symbol file with UUID %s", strm.GetData()); } - return false; + return; } } else { StreamString strm; @@ -2592,12 +2846,12 @@ protected: "Unable to locate the executable or symbol file with UUID %s", strm.GetData()); result.SetError(error); - return false; + return; } } else { result.AppendError( "one or more executable image paths must be specified"); - return false; + return; } } else { for (auto &entry : args.entries()) { @@ -2625,7 +2879,7 @@ protected: else result.AppendErrorWithFormat("unsupported module: %s", entry.c_str()); - return false; + return; } else { flush = true; } @@ -2650,8 +2904,6 @@ protected: if (process) process->Flush(); } - - return result.Succeeded(); } }; @@ -2692,7 +2944,7 @@ public: Options *GetOptions() override { return &m_option_group; } protected: - bool DoExecute(Args &args, CommandReturnObject &result) override { + void DoExecute(Args &args, CommandReturnObject &result) override { Target *target = &GetSelectedTarget(); const bool load = m_load_option.GetOptionValue().GetCurrentValue(); const bool set_pc = m_pc_option.GetOptionValue().GetCurrentValue(); @@ -2765,14 +3017,14 @@ protected: } else { result.AppendError("one or more section name + load " "address pair must be specified"); - return false; + return; } } else { if (m_slide_option.GetOptionValue().OptionWasSet()) { result.AppendError("The \"--slide <offset>\" option can't " "be used in conjunction with setting " "section load addresses.\n"); - return false; + return; } for (size_t i = 0; i < argc; i += 2) { @@ -2834,22 +3086,22 @@ protected: Address file_entry = objfile->GetEntryPointAddress(); if (!process) { result.AppendError("No process"); - return false; + return; } if (set_pc && !file_entry.IsValid()) { result.AppendError("No entry address in object file"); - return false; + return; } std::vector<ObjectFile::LoadableData> loadables( objfile->GetLoadableData(*target)); if (loadables.size() == 0) { result.AppendError("No loadable sections"); - return false; + return; } Status error = process->WriteObjectFile(std::move(loadables)); if (error.Fail()) { result.AppendError(error.AsCString()); - return false; + return; } if (set_pc) { ThreadList &thread_list = process->GetThreadList(); @@ -2911,9 +3163,7 @@ protected: } else { result.AppendError("either the \"--file <module>\" or the \"--uuid " "<uuid>\" option must be specified.\n"); - return false; } - return result.Succeeded(); } OptionGroupOptions m_option_group; @@ -2985,7 +3235,7 @@ public: Options *GetOptions() override { return &m_options; } protected: - bool DoExecute(Args &command, CommandReturnObject &result) override { + void DoExecute(Args &command, CommandReturnObject &result) override { Target *target = GetDebugger().GetSelectedTarget().get(); const bool use_global_module_list = m_options.m_use_global_module_list; // Define a local module list here to ensure it lives longer than any @@ -2995,7 +3245,7 @@ protected: if (target == nullptr && !use_global_module_list) { result.AppendError("invalid target, create a debug target using the " "'target create' command"); - return false; + return; } else { if (target) { uint32_t addr_byte_size = @@ -3028,7 +3278,7 @@ protected: result.AppendError( "Can only look up modules by address with a valid target."); } - return result.Succeeded(); + return; } size_t num_modules = 0; @@ -3058,7 +3308,7 @@ protected: if (argc == 1) { result.AppendErrorWithFormat("no modules found that match '%s'", arg.c_str()); - return false; + return; } } } @@ -3104,10 +3354,9 @@ protected: result.AppendError( "the target has no associated executable images"); } - return false; + return; } } - return result.Succeeded(); } void PrintModule(Target *target, Module *module, int indent, Stream &strm) { @@ -3341,7 +3590,7 @@ public: Options *GetOptions() override { return &m_options; } protected: - bool DoExecute(Args &command, CommandReturnObject &result) override { + void DoExecute(Args &command, CommandReturnObject &result) override { Target *target = m_exe_ctx.GetTargetPtr(); Process *process = m_exe_ctx.GetProcessPtr(); ABI *abi = nullptr; @@ -3351,19 +3600,19 @@ protected: if (process == nullptr) { result.AppendError( "You must have a process running to use this command."); - return false; + return; } ThreadList threads(process->GetThreadList()); if (threads.GetSize() == 0) { result.AppendError("The process must be paused to use this command."); - return false; + return; } ThreadSP thread(threads.GetThreadAtIndex(0)); if (!thread) { result.AppendError("The process must be paused to use this command."); - return false; + return; } SymbolContextList sc_list; @@ -3390,13 +3639,13 @@ protected: } else { result.AppendError( "address-expression or function name option must be specified."); - return false; + return; } if (sc_list.GetSize() == 0) { result.AppendErrorWithFormat("no unwind data found that matches '%s'.", m_options.m_str.c_str()); - return false; + return; } for (const SymbolContext &sc : sc_list) { @@ -3595,7 +3844,6 @@ protected: result.GetOutputStream().Printf("\n"); } - return result.Succeeded(); } CommandOptions m_options; @@ -3899,7 +4147,7 @@ public: } protected: - bool DoExecute(Args &command, CommandReturnObject &result) override { + void DoExecute(Args &command, CommandReturnObject &result) override { Target *target = &GetSelectedTarget(); bool syntax_error = false; uint32_t i; @@ -3920,7 +4168,7 @@ protected: num_successful_lookups++; if (!m_options.m_print_all) { result.SetStatus(eReturnStatusSuccessFinishResult); - return result.Succeeded(); + return; } } @@ -3930,7 +4178,7 @@ protected: std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex()); if (target_modules.GetSize() == 0) { result.AppendError("the target has no associated executable images"); - return false; + return; } for (ModuleSP module_sp : target_modules.ModulesNoLocking()) { @@ -3970,7 +4218,6 @@ protected: result.SetStatus(eReturnStatusSuccessFinishResult); else result.SetStatus(eReturnStatusFailed); - return result.Succeeded(); } CommandOptions m_options; @@ -4258,7 +4505,7 @@ protected: bool DownloadObjectAndSymbolFile(ModuleSpec &module_spec, CommandReturnObject &result, bool &flush) { Status error; - if (Symbols::DownloadObjectAndSymbolFile(module_spec, error)) { + if (PluginManager::DownloadObjectAndSymbolFile(module_spec, error)) { if (module_spec.GetSymbolFileSpec()) return AddModuleSymbols(m_exe_ctx.GetTargetPtr(), module_spec, flush, result); @@ -4419,7 +4666,7 @@ protected: return true; } - bool DoExecute(Args &args, CommandReturnObject &result) override { + void DoExecute(Args &args, CommandReturnObject &result) override { Target *target = m_exe_ctx.GetTargetPtr(); result.SetStatus(eReturnStatusFailed); bool flush = false; @@ -4504,7 +4751,6 @@ protected: if (process) process->Flush(); } - return result.Succeeded(); } OptionGroupOptions m_option_group; @@ -4806,7 +5052,7 @@ protected: io_handler.SetIsDone(true); } - bool DoExecute(Args &command, CommandReturnObject &result) override { + void DoExecute(Args &command, CommandReturnObject &result) override { m_stop_hook_sp.reset(); Target &target = GetSelectedOrDummyTarget(); @@ -4903,7 +5149,7 @@ protected: result.AppendErrorWithFormat("Couldn't add stop hook: %s", error.AsCString()); target.UndoCreateStopHook(new_hook_sp->GetID()); - return false; + return; } } else { m_stop_hook_sp = new_hook_sp; @@ -4911,8 +5157,6 @@ protected: *this); // IOHandlerDelegate } result.SetStatus(eReturnStatusSuccessFinishNoResult); - - return result.Succeeded(); } private: @@ -4942,19 +5186,21 @@ public: void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override { + if (request.GetCursorIndex()) + return; lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), lldb::eStopHookIDCompletion, request, nullptr); } protected: - bool DoExecute(Args &command, CommandReturnObject &result) override { + void DoExecute(Args &command, CommandReturnObject &result) override { Target &target = GetSelectedOrDummyTarget(); // FIXME: see if we can use the breakpoint id style parser? size_t num_args = command.GetArgumentCount(); if (num_args == 0) { if (!m_interpreter.Confirm("Delete all stop hooks?", true)) { result.SetStatus(eReturnStatusFailed); - return false; + return; } else { target.RemoveAllStopHooks(); } @@ -4964,17 +5210,16 @@ protected: if (!llvm::to_integer(command.GetArgumentAtIndex(i), user_id)) { result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i)); - return false; + return; } if (!target.RemoveStopHookByID(user_id)) { result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i)); - return false; + return; } } } result.SetStatus(eReturnStatusSuccessFinishNoResult); - return result.Succeeded(); } }; @@ -5004,7 +5249,7 @@ public: } protected: - bool DoExecute(Args &command, CommandReturnObject &result) override { + void DoExecute(Args &command, CommandReturnObject &result) override { Target &target = GetSelectedOrDummyTarget(); // FIXME: see if we can use the breakpoint id style parser? size_t num_args = command.GetArgumentCount(); @@ -5018,18 +5263,17 @@ protected: if (!llvm::to_integer(command.GetArgumentAtIndex(i), user_id)) { result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i)); - return false; + return; } success = target.SetStopHookActiveStateByID(user_id, m_enable); if (!success) { result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i)); - return false; + return; } } } result.SetStatus(eReturnStatusSuccessFinishNoResult); - return result.Succeeded(); } private: @@ -5049,7 +5293,7 @@ public: ~CommandObjectTargetStopHookList() override = default; protected: - bool DoExecute(Args &command, CommandReturnObject &result) override { + void DoExecute(Args &command, CommandReturnObject &result) override { Target &target = GetSelectedOrDummyTarget(); size_t num_hooks = target.GetNumStopHooks(); @@ -5065,7 +5309,6 @@ protected: } } result.SetStatus(eReturnStatusSuccessFinishResult); - return result.Succeeded(); } }; @@ -5115,14 +5358,13 @@ public: ~CommandObjectTargetDumpTypesystem() override = default; protected: - bool DoExecute(Args &command, CommandReturnObject &result) override { + void DoExecute(Args &command, CommandReturnObject &result) override { // Go over every scratch TypeSystem and dump to the command output. for (lldb::TypeSystemSP ts : GetSelectedTarget().GetScratchTypeSystems()) if (ts) ts->Dump(result.GetOutputStream().AsRawOstream()); result.SetStatus(eReturnStatusSuccessFinishResult); - return result.Succeeded(); } }; @@ -5141,11 +5383,10 @@ public: ~CommandObjectTargetDumpSectionLoadList() override = default; protected: - bool DoExecute(Args &command, CommandReturnObject &result) override { + void DoExecute(Args &command, CommandReturnObject &result) override { Target &target = GetSelectedTarget(); target.GetSectionLoadList().Dump(result.GetOutputStream(), &target); result.SetStatus(eReturnStatusSuccessFinishResult); - return result.Succeeded(); } }; |
