diff options
Diffstat (limited to 'contrib/llvm-project/lldb/source/Commands')
57 files changed, 1821 insertions, 1033 deletions
diff --git a/contrib/llvm-project/lldb/source/Commands/CommandCompletions.cpp b/contrib/llvm-project/lldb/source/Commands/CommandCompletions.cpp index d9bee66b442a..48df77357201 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandCompletions.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandCompletions.cpp @@ -1,4 +1,4 @@ -//===-- CommandCompletions.cpp ----------------------------------*- C++ -*-===// +//===-- CommandCompletions.cpp --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -18,6 +18,7 @@ #include "lldb/Interpreter/OptionValueProperties.h" #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/Variable.h" +#include "lldb/Target/RegisterContext.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/StreamString.h" #include "lldb/Utility/TildeExpressionResolver.h" @@ -27,19 +28,17 @@ using namespace lldb_private; -CommandCompletions::CommonCompletionElement - CommandCompletions::g_common_completions[] = { - {eCustomCompletion, nullptr}, - {eSourceFileCompletion, CommandCompletions::SourceFiles}, - {eDiskFileCompletion, CommandCompletions::DiskFiles}, - {eDiskDirectoryCompletion, CommandCompletions::DiskDirectories}, - {eSymbolCompletion, CommandCompletions::Symbols}, - {eModuleCompletion, CommandCompletions::Modules}, - {eSettingsNameCompletion, CommandCompletions::SettingsNames}, - {ePlatformPluginCompletion, CommandCompletions::PlatformPluginNames}, - {eArchitectureCompletion, CommandCompletions::ArchitectureNames}, - {eVariablePathCompletion, CommandCompletions::VariablePath}, - {eNoCompletion, nullptr} // This one has to be last in the list. +// This is the command completion callback that is used to complete the +// argument of the option it is bound to (in the OptionDefinition table +// below). +typedef void (*CompletionCallback)(CommandInterpreter &interpreter, + CompletionRequest &request, + // A search filter to limit the search... + lldb_private::SearchFilter *searcher); + +struct CommonCompletionElement { + uint32_t type; + CompletionCallback callback; }; bool CommandCompletions::InvokeCommonCompletionCallbacks( @@ -47,27 +46,245 @@ bool CommandCompletions::InvokeCommonCompletionCallbacks( CompletionRequest &request, SearchFilter *searcher) { bool handled = false; - if (completion_mask & eCustomCompletion) - return false; + const CommonCompletionElement common_completions[] = { + {eSourceFileCompletion, CommandCompletions::SourceFiles}, + {eDiskFileCompletion, CommandCompletions::DiskFiles}, + {eDiskDirectoryCompletion, CommandCompletions::DiskDirectories}, + {eSymbolCompletion, CommandCompletions::Symbols}, + {eModuleCompletion, CommandCompletions::Modules}, + {eSettingsNameCompletion, CommandCompletions::SettingsNames}, + {ePlatformPluginCompletion, CommandCompletions::PlatformPluginNames}, + {eArchitectureCompletion, CommandCompletions::ArchitectureNames}, + {eVariablePathCompletion, CommandCompletions::VariablePath}, + {eRegisterCompletion, CommandCompletions::Registers}, + {eBreakpointCompletion, CommandCompletions::Breakpoints}, + {eProcessPluginCompletion, CommandCompletions::ProcessPluginNames}, + {eNoCompletion, nullptr} // This one has to be last in the list. + }; for (int i = 0;; i++) { - if (g_common_completions[i].type == eNoCompletion) + if (common_completions[i].type == eNoCompletion) break; - else if ((g_common_completions[i].type & completion_mask) == - g_common_completions[i].type && - g_common_completions[i].callback != nullptr) { + else if ((common_completions[i].type & completion_mask) == + common_completions[i].type && + common_completions[i].callback != nullptr) { handled = true; - g_common_completions[i].callback(interpreter, request, searcher); + common_completions[i].callback(interpreter, request, searcher); } } return handled; } +namespace { +// The Completer class is a convenient base class for building searchers that +// go along with the SearchFilter passed to the standard Completer functions. +class Completer : public Searcher { +public: + Completer(CommandInterpreter &interpreter, CompletionRequest &request) + : m_interpreter(interpreter), m_request(request) {} + + ~Completer() override = default; + + CallbackReturn SearchCallback(SearchFilter &filter, SymbolContext &context, + Address *addr) override = 0; + + lldb::SearchDepth GetDepth() override = 0; + + virtual void DoCompletion(SearchFilter *filter) = 0; + +protected: + CommandInterpreter &m_interpreter; + CompletionRequest &m_request; + +private: + Completer(const Completer &) = delete; + const Completer &operator=(const Completer &) = delete; +}; +} // namespace + +// SourceFileCompleter implements the source file completer +namespace { +class SourceFileCompleter : public Completer { +public: + SourceFileCompleter(CommandInterpreter &interpreter, + CompletionRequest &request) + : Completer(interpreter, request), m_matching_files() { + FileSpec partial_spec(m_request.GetCursorArgumentPrefix()); + m_file_name = partial_spec.GetFilename().GetCString(); + m_dir_name = partial_spec.GetDirectory().GetCString(); + } + + lldb::SearchDepth GetDepth() override { return lldb::eSearchDepthCompUnit; } + + Searcher::CallbackReturn SearchCallback(SearchFilter &filter, + SymbolContext &context, + Address *addr) override { + if (context.comp_unit != nullptr) { + const char *cur_file_name = + context.comp_unit->GetPrimaryFile().GetFilename().GetCString(); + const char *cur_dir_name = + context.comp_unit->GetPrimaryFile().GetDirectory().GetCString(); + + bool match = false; + if (m_file_name && cur_file_name && + strstr(cur_file_name, m_file_name) == cur_file_name) + match = true; + + if (match && m_dir_name && cur_dir_name && + strstr(cur_dir_name, m_dir_name) != cur_dir_name) + match = false; + + if (match) { + m_matching_files.AppendIfUnique(context.comp_unit->GetPrimaryFile()); + } + } + return Searcher::eCallbackReturnContinue; + } + + void DoCompletion(SearchFilter *filter) override { + filter->Search(*this); + // Now convert the filelist to completions: + for (size_t i = 0; i < m_matching_files.GetSize(); i++) { + m_request.AddCompletion( + m_matching_files.GetFileSpecAtIndex(i).GetFilename().GetCString()); + } + } + +private: + FileSpecList m_matching_files; + const char *m_file_name; + const char *m_dir_name; + + SourceFileCompleter(const SourceFileCompleter &) = delete; + const SourceFileCompleter &operator=(const SourceFileCompleter &) = delete; +}; +} // namespace + +static bool regex_chars(const char comp) { + return llvm::StringRef("[](){}+.*|^$\\?").contains(comp); +} + +namespace { +class SymbolCompleter : public Completer { + +public: + SymbolCompleter(CommandInterpreter &interpreter, CompletionRequest &request) + : Completer(interpreter, request) { + std::string regex_str; + if (!m_request.GetCursorArgumentPrefix().empty()) { + regex_str.append("^"); + regex_str.append(std::string(m_request.GetCursorArgumentPrefix())); + } else { + // Match anything since the completion string is empty + regex_str.append("."); + } + std::string::iterator pos = + find_if(regex_str.begin() + 1, regex_str.end(), regex_chars); + while (pos < regex_str.end()) { + pos = regex_str.insert(pos, '\\'); + pos = find_if(pos + 2, regex_str.end(), regex_chars); + } + m_regex = RegularExpression(regex_str); + } + + lldb::SearchDepth GetDepth() override { return lldb::eSearchDepthModule; } + + Searcher::CallbackReturn SearchCallback(SearchFilter &filter, + SymbolContext &context, + Address *addr) override { + if (context.module_sp) { + SymbolContextList sc_list; + const bool include_symbols = true; + const bool include_inlines = true; + context.module_sp->FindFunctions(m_regex, include_symbols, + include_inlines, sc_list); + + SymbolContext sc; + // Now add the functions & symbols to the list - only add if unique: + for (uint32_t i = 0; i < sc_list.GetSize(); i++) { + if (sc_list.GetContextAtIndex(i, sc)) { + ConstString func_name = sc.GetFunctionName(Mangled::ePreferDemangled); + // Ensure that the function name matches the regex. This is more than + // a sanity check. It is possible that the demangled function name + // does not start with the prefix, for example when it's in an + // anonymous namespace. + if (!func_name.IsEmpty() && m_regex.Execute(func_name.GetStringRef())) + m_match_set.insert(func_name); + } + } + } + return Searcher::eCallbackReturnContinue; + } + + void DoCompletion(SearchFilter *filter) override { + filter->Search(*this); + collection::iterator pos = m_match_set.begin(), end = m_match_set.end(); + for (pos = m_match_set.begin(); pos != end; pos++) + m_request.AddCompletion((*pos).GetCString()); + } + +private: + RegularExpression m_regex; + typedef std::set<ConstString> collection; + collection m_match_set; + + SymbolCompleter(const SymbolCompleter &) = delete; + const SymbolCompleter &operator=(const SymbolCompleter &) = delete; +}; +} // namespace + +namespace { +class ModuleCompleter : public Completer { +public: + ModuleCompleter(CommandInterpreter &interpreter, CompletionRequest &request) + : Completer(interpreter, request) { + FileSpec partial_spec(m_request.GetCursorArgumentPrefix()); + m_file_name = partial_spec.GetFilename().GetCString(); + m_dir_name = partial_spec.GetDirectory().GetCString(); + } + + lldb::SearchDepth GetDepth() override { return lldb::eSearchDepthModule; } + + Searcher::CallbackReturn SearchCallback(SearchFilter &filter, + SymbolContext &context, + Address *addr) override { + if (context.module_sp) { + const char *cur_file_name = + context.module_sp->GetFileSpec().GetFilename().GetCString(); + const char *cur_dir_name = + context.module_sp->GetFileSpec().GetDirectory().GetCString(); + + bool match = false; + if (m_file_name && cur_file_name && + strstr(cur_file_name, m_file_name) == cur_file_name) + match = true; + + if (match && m_dir_name && cur_dir_name && + strstr(cur_dir_name, m_dir_name) != cur_dir_name) + match = false; + + if (match) { + m_request.AddCompletion(cur_file_name); + } + } + return Searcher::eCallbackReturnContinue; + } + + void DoCompletion(SearchFilter *filter) override { filter->Search(*this); } + +private: + const char *m_file_name; + const char *m_dir_name; + + ModuleCompleter(const ModuleCompleter &) = delete; + const ModuleCompleter &operator=(const ModuleCompleter &) = delete; +}; +} // namespace + void CommandCompletions::SourceFiles(CommandInterpreter &interpreter, CompletionRequest &request, SearchFilter *searcher) { - // Find some way to switch "include support files..." - SourceFileCompleter completer(interpreter, false, request); + SourceFileCompleter completer(interpreter, request); if (searcher == nullptr) { lldb::TargetSP target_sp = interpreter.GetDebugger().GetSelectedTarget(); @@ -295,7 +512,7 @@ void CommandCompletions::SettingsNames(CommandInterpreter &interpreter, if (properties_sp) { StreamString strm; properties_sp->DumpValue(nullptr, strm, OptionValue::eDumpOptionName); - const std::string &str = strm.GetString(); + const std::string &str = std::string(strm.GetString()); g_property_names.SplitIntoLines(str.c_str(), str.size()); } } @@ -323,185 +540,57 @@ void CommandCompletions::VariablePath(CommandInterpreter &interpreter, Variable::AutoComplete(interpreter.GetExecutionContext(), request); } -CommandCompletions::Completer::Completer(CommandInterpreter &interpreter, - CompletionRequest &request) - : m_interpreter(interpreter), m_request(request) {} - -CommandCompletions::Completer::~Completer() = default; - -// SourceFileCompleter - -CommandCompletions::SourceFileCompleter::SourceFileCompleter( - CommandInterpreter &interpreter, bool include_support_files, - CompletionRequest &request) - : CommandCompletions::Completer(interpreter, request), - m_include_support_files(include_support_files), m_matching_files() { - FileSpec partial_spec(m_request.GetCursorArgumentPrefix()); - m_file_name = partial_spec.GetFilename().GetCString(); - m_dir_name = partial_spec.GetDirectory().GetCString(); -} - -lldb::SearchDepth CommandCompletions::SourceFileCompleter::GetDepth() { - return lldb::eSearchDepthCompUnit; -} - -Searcher::CallbackReturn -CommandCompletions::SourceFileCompleter::SearchCallback(SearchFilter &filter, - SymbolContext &context, - Address *addr) { - if (context.comp_unit != nullptr) { - if (m_include_support_files) { - FileSpecList supporting_files = context.comp_unit->GetSupportFiles(); - for (size_t sfiles = 0; sfiles < supporting_files.GetSize(); sfiles++) { - const FileSpec &sfile_spec = - supporting_files.GetFileSpecAtIndex(sfiles); - const char *sfile_file_name = sfile_spec.GetFilename().GetCString(); - const char *sfile_dir_name = sfile_spec.GetFilename().GetCString(); - bool match = false; - if (m_file_name && sfile_file_name && - strstr(sfile_file_name, m_file_name) == sfile_file_name) - match = true; - if (match && m_dir_name && sfile_dir_name && - strstr(sfile_dir_name, m_dir_name) != sfile_dir_name) - match = false; - - if (match) { - m_matching_files.AppendIfUnique(sfile_spec); - } - } - } else { - const char *cur_file_name = - context.comp_unit->GetPrimaryFile().GetFilename().GetCString(); - const char *cur_dir_name = - context.comp_unit->GetPrimaryFile().GetDirectory().GetCString(); - - bool match = false; - if (m_file_name && cur_file_name && - strstr(cur_file_name, m_file_name) == cur_file_name) - match = true; - - if (match && m_dir_name && cur_dir_name && - strstr(cur_dir_name, m_dir_name) != cur_dir_name) - match = false; - - if (match) { - m_matching_files.AppendIfUnique(context.comp_unit->GetPrimaryFile()); - } - } - } - return Searcher::eCallbackReturnContinue; -} - -void CommandCompletions::SourceFileCompleter::DoCompletion( - SearchFilter *filter) { - filter->Search(*this); - // Now convert the filelist to completions: - for (size_t i = 0; i < m_matching_files.GetSize(); i++) { - m_request.AddCompletion( - m_matching_files.GetFileSpecAtIndex(i).GetFilename().GetCString()); +void CommandCompletions::Registers(CommandInterpreter &interpreter, + CompletionRequest &request, + SearchFilter *searcher) { + std::string reg_prefix = ""; + if (request.GetCursorArgumentPrefix().startswith("$")) + reg_prefix = "$"; + + RegisterContext *reg_ctx = + interpreter.GetExecutionContext().GetRegisterContext(); + const size_t reg_num = reg_ctx->GetRegisterCount(); + for (size_t reg_idx = 0; reg_idx < reg_num; ++reg_idx) { + const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex(reg_idx); + request.TryCompleteCurrentArg(reg_prefix + reg_info->name, + reg_info->alt_name); } } -// SymbolCompleter - -static bool regex_chars(const char comp) { - return llvm::StringRef("[](){}+.*|^$\\?").contains(comp); -} +void CommandCompletions::Breakpoints(CommandInterpreter &interpreter, + CompletionRequest &request, + SearchFilter *searcher) { + lldb::TargetSP target = interpreter.GetDebugger().GetSelectedTarget(); + if (!target) + return; -CommandCompletions::SymbolCompleter::SymbolCompleter( - CommandInterpreter &interpreter, CompletionRequest &request) - : CommandCompletions::Completer(interpreter, request) { - std::string regex_str; - if (!m_request.GetCursorArgumentPrefix().empty()) { - regex_str.append("^"); - regex_str.append(m_request.GetCursorArgumentPrefix()); - } else { - // Match anything since the completion string is empty - regex_str.append("."); - } - std::string::iterator pos = - find_if(regex_str.begin() + 1, regex_str.end(), regex_chars); - while (pos < regex_str.end()) { - pos = regex_str.insert(pos, '\\'); - pos = find_if(pos + 2, regex_str.end(), regex_chars); - } - m_regex = RegularExpression(regex_str); -} + const BreakpointList &breakpoints = target->GetBreakpointList(); -lldb::SearchDepth CommandCompletions::SymbolCompleter::GetDepth() { - return lldb::eSearchDepthModule; -} + std::unique_lock<std::recursive_mutex> lock; + target->GetBreakpointList().GetListMutex(lock); -Searcher::CallbackReturn CommandCompletions::SymbolCompleter::SearchCallback( - SearchFilter &filter, SymbolContext &context, Address *addr) { - if (context.module_sp) { - SymbolContextList sc_list; - const bool include_symbols = true; - const bool include_inlines = true; - context.module_sp->FindFunctions(m_regex, include_symbols, include_inlines, - sc_list); - - SymbolContext sc; - // Now add the functions & symbols to the list - only add if unique: - for (uint32_t i = 0; i < sc_list.GetSize(); i++) { - if (sc_list.GetContextAtIndex(i, sc)) { - ConstString func_name = sc.GetFunctionName(Mangled::ePreferDemangled); - // Ensure that the function name matches the regex. This is more than a - // sanity check. It is possible that the demangled function name does - // not start with the prefix, for example when it's in an anonymous - // namespace. - if (!func_name.IsEmpty() && m_regex.Execute(func_name.GetStringRef())) - m_match_set.insert(func_name); - } - } - } - return Searcher::eCallbackReturnContinue; -} + size_t num_breakpoints = breakpoints.GetSize(); + if (num_breakpoints == 0) + return; -void CommandCompletions::SymbolCompleter::DoCompletion(SearchFilter *filter) { - filter->Search(*this); - collection::iterator pos = m_match_set.begin(), end = m_match_set.end(); - for (pos = m_match_set.begin(); pos != end; pos++) - m_request.AddCompletion((*pos).GetCString()); -} + for (size_t i = 0; i < num_breakpoints; ++i) { + lldb::BreakpointSP bp = breakpoints.GetBreakpointAtIndex(i); -// ModuleCompleter -CommandCompletions::ModuleCompleter::ModuleCompleter( - CommandInterpreter &interpreter, CompletionRequest &request) - : CommandCompletions::Completer(interpreter, request) { - FileSpec partial_spec(m_request.GetCursorArgumentPrefix()); - m_file_name = partial_spec.GetFilename().GetCString(); - m_dir_name = partial_spec.GetDirectory().GetCString(); -} + StreamString s; + bp->GetDescription(&s, lldb::eDescriptionLevelBrief); + llvm::StringRef bp_info = s.GetString(); -lldb::SearchDepth CommandCompletions::ModuleCompleter::GetDepth() { - return lldb::eSearchDepthModule; -} + const size_t colon_pos = bp_info.find_first_of(':'); + if (colon_pos != llvm::StringRef::npos) + bp_info = bp_info.drop_front(colon_pos + 2); -Searcher::CallbackReturn CommandCompletions::ModuleCompleter::SearchCallback( - SearchFilter &filter, SymbolContext &context, Address *addr) { - if (context.module_sp) { - const char *cur_file_name = - context.module_sp->GetFileSpec().GetFilename().GetCString(); - const char *cur_dir_name = - context.module_sp->GetFileSpec().GetDirectory().GetCString(); - - bool match = false; - if (m_file_name && cur_file_name && - strstr(cur_file_name, m_file_name) == cur_file_name) - match = true; - - if (match && m_dir_name && cur_dir_name && - strstr(cur_dir_name, m_dir_name) != cur_dir_name) - match = false; - - if (match) { - m_request.AddCompletion(cur_file_name); - } + request.TryCompleteCurrentArg(std::to_string(bp->GetID()), bp_info); } - return Searcher::eCallbackReturnContinue; } -void CommandCompletions::ModuleCompleter::DoCompletion(SearchFilter *filter) { - filter->Search(*this); -} +void CommandCompletions::ProcessPluginNames(CommandInterpreter &interpreter, + CompletionRequest &request, + SearchFilter *searcher) { + PluginManager::AutoCompleteProcessName(request.GetCursorArgumentPrefix(), + request); +}
\ No newline at end of file diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectApropos.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectApropos.cpp index 15a20737273d..6e1e1f061733 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectApropos.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectApropos.cpp @@ -1,5 +1,4 @@ -//===-- CommandObjectApropos.cpp ---------------------------------*- C++ -//-*-===// +//===-- CommandObjectApropos.cpp ------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectApropos.h b/contrib/llvm-project/lldb/source/Commands/CommandObjectApropos.h index 37d86b17d1a2..042753f24032 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectApropos.h +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectApropos.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CommandObjectApropos_h_ -#define liblldb_CommandObjectApropos_h_ +#ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTAPROPOS_H +#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTAPROPOS_H #include "lldb/Interpreter/CommandObject.h" @@ -28,4 +28,4 @@ protected: } // namespace lldb_private -#endif // liblldb_CommandObjectApropos_h_ +#endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTAPROPOS_H diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectBreakpoint.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectBreakpoint.cpp index 7c4c50ecf3f9..be7ef8a1b60b 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectBreakpoint.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectBreakpoint.cpp @@ -1,4 +1,4 @@ -//===-- CommandObjectBreakpoint.cpp -----------------------------*- C++ -*-===// +//===-- CommandObjectBreakpoint.cpp ---------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -70,7 +70,7 @@ public: m_bp_opts.m_set_flags.Set(BreakpointOptions::eCondition); break; case 'C': - m_commands.push_back(option_arg); + m_commands.push_back(std::string(option_arg)); break; case 'd': m_bp_opts.SetEnabled(false); @@ -270,11 +270,11 @@ public: break; case 'b': - m_func_names.push_back(option_arg); + m_func_names.push_back(std::string(option_arg)); m_func_name_type_mask |= eFunctionNameTypeBase; break; - case 'C': + case 'u': if (option_arg.getAsInteger(0, m_column)) error.SetErrorStringWithFormat("invalid column number: %s", option_arg.str().c_str()); @@ -320,7 +320,7 @@ public: break; case 'F': - m_func_names.push_back(option_arg); + m_func_names.push_back(std::string(option_arg)); m_func_name_type_mask |= eFunctionNameTypeFull; break; @@ -383,18 +383,18 @@ public: } case 'M': - m_func_names.push_back(option_arg); + m_func_names.push_back(std::string(option_arg)); m_func_name_type_mask |= eFunctionNameTypeMethod; break; case 'n': - m_func_names.push_back(option_arg); + m_func_names.push_back(std::string(option_arg)); m_func_name_type_mask |= eFunctionNameTypeAuto; break; case 'N': { if (BreakpointID::StringIsBreakpointName(option_arg, error)) - m_breakpoint_names.push_back(option_arg); + m_breakpoint_names.push_back(std::string(option_arg)); else error.SetErrorStringWithFormat("Invalid breakpoint name: %s", option_arg.str().c_str()); @@ -415,11 +415,11 @@ public: break; case 'p': - m_source_text_regexp.assign(option_arg); + m_source_text_regexp.assign(std::string(option_arg)); break; case 'r': - m_func_regexp.assign(option_arg); + m_func_regexp.assign(std::string(option_arg)); break; case 's': @@ -427,7 +427,7 @@ public: break; case 'S': - m_func_names.push_back(option_arg); + m_func_names.push_back(std::string(option_arg)); m_func_name_type_mask |= eFunctionNameTypeSelector; break; @@ -441,7 +441,7 @@ public: } break; case 'X': - m_source_regex_func_names.insert(option_arg); + m_source_regex_func_names.insert(std::string(option_arg)); break; default: @@ -620,8 +620,16 @@ protected: RegularExpression regexp(m_options.m_func_regexp); if (llvm::Error err = regexp.GetError()) { result.AppendErrorWithFormat( - "Function name regular expression could not be compiled: \"%s\"", + "Function name regular expression could not be compiled: %s", llvm::toString(std::move(err)).c_str()); + // Check if the incorrect regex looks like a globbing expression and + // warn the user about it. + if (!m_options.m_func_regexp.empty()) { + if (m_options.m_func_regexp[0] == '*' || + m_options.m_func_regexp[0] == '?') + result.AppendWarning( + "Function name regex does not accept glob patterns."); + } result.SetStatus(eReturnStatusFailed); return false; } @@ -811,6 +819,14 @@ public: ~CommandObjectBreakpointModify() override = default; + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { + CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), CommandCompletions::eBreakpointCompletion, + request, nullptr); + } + Options *GetOptions() override { return &m_options; } protected: @@ -877,6 +893,14 @@ public: ~CommandObjectBreakpointEnable() override = default; + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { + CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), CommandCompletions::eBreakpointCompletion, + request, nullptr); + } + protected: bool DoExecute(Args &command, CommandReturnObject &result) override { Target &target = GetSelectedOrDummyTarget(); @@ -985,6 +1009,14 @@ the second re-enables the first location."); ~CommandObjectBreakpointDisable() override = default; + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { + CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), CommandCompletions::eBreakpointCompletion, + request, nullptr); + } + protected: bool DoExecute(Args &command, CommandReturnObject &result) override { Target &target = GetSelectedOrDummyTarget(); @@ -1231,7 +1263,7 @@ public: switch (short_option) { case 'f': - m_filename.assign(option_arg); + m_filename.assign(std::string(option_arg)); break; case 'l': @@ -1363,6 +1395,14 @@ public: ~CommandObjectBreakpointDelete() override = default; + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { + CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), CommandCompletions::eBreakpointCompletion, + request, nullptr); + } + Options *GetOptions() override { return &m_options; } class CommandOptions : public Options { @@ -1730,6 +1770,14 @@ public: ~CommandObjectBreakpointNameAdd() override = default; + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { + CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), CommandCompletions::eBreakpointCompletion, + request, nullptr); + } + Options *GetOptions() override { return &m_option_group; } protected: @@ -1809,6 +1857,14 @@ public: ~CommandObjectBreakpointNameDelete() override = default; + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { + CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), CommandCompletions::eBreakpointCompletion, + request, nullptr); + } + Options *GetOptions() override { return &m_option_group; } protected: @@ -1978,14 +2034,7 @@ public: "Read and set the breakpoints previously saved to " "a file with \"breakpoint write\". ", nullptr), - m_options() { - CommandArgumentEntry arg; - CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, - eArgTypeBreakpointIDRange); - // Add the entry for the first argument for this command to the object's - // arguments vector. - m_arguments.push_back(arg); - } + m_options() {} ~CommandObjectBreakpointRead() override = default; @@ -2004,7 +2053,7 @@ public: switch (short_option) { case 'f': - m_filename.assign(option_arg); + m_filename.assign(std::string(option_arg)); break; case 'N': { Status name_error; @@ -2013,7 +2062,7 @@ public: error.SetErrorStringWithFormat("Invalid breakpoint name: %s", name_error.AsCString()); } - m_names.push_back(option_arg); + m_names.push_back(std::string(option_arg)); break; } default: @@ -2107,6 +2156,14 @@ public: ~CommandObjectBreakpointWrite() override = default; + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { + CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), CommandCompletions::eBreakpointCompletion, + request, nullptr); + } + Options *GetOptions() override { return &m_options; } class CommandOptions : public Options { @@ -2122,7 +2179,7 @@ public: switch (short_option) { case 'f': - m_filename.assign(option_arg); + m_filename.assign(std::string(option_arg)); break; case 'a': m_append = true; diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectBreakpoint.h b/contrib/llvm-project/lldb/source/Commands/CommandObjectBreakpoint.h index b29bbc0a74fa..6625652b260b 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectBreakpoint.h +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectBreakpoint.h @@ -6,9 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CommandObjectBreakpoint_h_ -#define liblldb_CommandObjectBreakpoint_h_ - +#ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTBREAKPOINT_H +#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTBREAKPOINT_H #include "lldb/Breakpoint/BreakpointName.h" #include "lldb/Interpreter/CommandObjectMultiword.h" @@ -46,4 +45,4 @@ private: } // namespace lldb_private -#endif // liblldb_CommandObjectBreakpoint_h_ +#endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTBREAKPOINT_H diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectBreakpointCommand.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectBreakpointCommand.cpp index bbd2ca570126..45df86589011 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectBreakpointCommand.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectBreakpointCommand.cpp @@ -1,4 +1,4 @@ -//===-- CommandObjectBreakpointCommand.cpp ----------------------*- C++ -*-===// +//===-- CommandObjectBreakpointCommand.cpp --------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -292,7 +292,7 @@ are no syntax errors may indicate that a function was declared but never called. switch (short_option) { case 'o': m_use_one_liner = true; - m_one_liner = option_arg; + m_one_liner = std::string(option_arg); break; case 's': diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectBreakpointCommand.h b/contrib/llvm-project/lldb/source/Commands/CommandObjectBreakpointCommand.h index fb246d47abfd..cb516d76ea37 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectBreakpointCommand.h +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectBreakpointCommand.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CommandObjectBreakpointCommand_h_ -#define liblldb_CommandObjectBreakpointCommand_h_ +#ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTBREAKPOINTCOMMAND_H +#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTBREAKPOINTCOMMAND_H #include "lldb/Interpreter/CommandObjectMultiword.h" @@ -24,4 +24,4 @@ public: } // namespace lldb_private -#endif // liblldb_CommandObjectBreakpointCommand_h_ +#endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTBREAKPOINTCOMMAND_H diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectCommands.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectCommands.cpp index 388db6fad631..d77e69c6f6a6 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectCommands.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectCommands.cpp @@ -1,4 +1,4 @@ -//===-- CommandObjectCommands.cpp -------------------------------*- C++ -*-===// +//===-- CommandObjectCommands.cpp -----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -527,14 +527,13 @@ protected: m_option_group.NotifyOptionParsingStarting(&exe_ctx); OptionsWithRaw args_with_suffix(raw_command_line); - const char *remainder = args_with_suffix.GetRawPart().c_str(); if (args_with_suffix.HasArgs()) if (!ParseOptionsAndNotify(args_with_suffix.GetArgs(), result, m_option_group, exe_ctx)) return false; - llvm::StringRef raw_command_string(remainder); + llvm::StringRef raw_command_string = args_with_suffix.GetRawPart(); Args args(raw_command_string); if (args.GetArgumentCount() < 2) { @@ -652,8 +651,8 @@ protected: } // Save these in std::strings since we're going to shift them off. - const std::string alias_command(args[0].ref()); - const std::string actual_command(args[1].ref()); + const std::string alias_command(std::string(args[0].ref())); + const std::string actual_command(std::string(args[1].ref())); args.Shift(); // Shift the alias command word off the argument vector. args.Shift(); // Shift the old command word off the argument vector. @@ -1007,7 +1006,7 @@ protected: *this, nullptr)); if (io_handler_sp) { - debugger.PushIOHandler(io_handler_sp); + debugger.RunIOHandlerAsync(io_handler_sp); result.SetStatus(eReturnStatusSuccessFinishNoResult); } } else { @@ -1114,12 +1113,12 @@ protected: } if (!check_only) { - std::string regex(regex_sed.substr(first_separator_char_pos + 1, - second_separator_char_pos - - first_separator_char_pos - 1)); - std::string subst(regex_sed.substr(second_separator_char_pos + 1, - third_separator_char_pos - - second_separator_char_pos - 1)); + std::string regex(std::string(regex_sed.substr( + first_separator_char_pos + 1, + second_separator_char_pos - first_separator_char_pos - 1))); + std::string subst(std::string(regex_sed.substr( + second_separator_char_pos + 1, + third_separator_char_pos - second_separator_char_pos - 1))); m_regex_cmd_up->AddRegexCommand(regex.c_str(), subst.c_str()); } return error; @@ -1150,10 +1149,10 @@ private: switch (short_option) { case 'h': - m_help.assign(option_arg); + m_help.assign(std::string(option_arg)); break; case 's': - m_syntax.assign(option_arg); + m_syntax.assign(std::string(option_arg)); break; default: llvm_unreachable("Unimplemented option"); @@ -1171,14 +1170,9 @@ private: return llvm::makeArrayRef(g_regex_options); } - // TODO: Convert these functions to return StringRefs. - const char *GetHelp() { - return (m_help.empty() ? nullptr : m_help.c_str()); - } + llvm::StringRef GetHelp() { return m_help; } - const char *GetSyntax() { - return (m_syntax.empty() ? nullptr : m_syntax.c_str()); - } + llvm::StringRef GetSyntax() { return m_syntax; } protected: // Instance variables to hold the values for command options. @@ -1526,15 +1520,15 @@ protected: switch (short_option) { case 'f': if (!option_arg.empty()) - m_funct_name = option_arg; + m_funct_name = std::string(option_arg); break; case 'c': if (!option_arg.empty()) - m_class_name = option_arg; + m_class_name = std::string(option_arg); break; case 'h': if (!option_arg.empty()) - m_short_help = option_arg; + m_short_help = std::string(option_arg); break; case 's': m_synchronicity = @@ -1627,7 +1621,6 @@ protected: io_handler.SetIsDone(true); } -protected: bool DoExecute(Args &command, CommandReturnObject &result) override { if (GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython) { result.AppendError("only scripting language supported for scripted " @@ -1643,7 +1636,7 @@ protected: } // Store the options in case we get multi-line input - m_cmd_name = command[0].ref(); + m_cmd_name = std::string(command[0].ref()); m_short_help.assign(m_options.m_short_help); m_synchronicity = m_options.m_synchronicity; @@ -1773,6 +1766,16 @@ public: ~CommandObjectCommandsScriptDelete() override = default; + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { + if (!m_interpreter.HasCommands() || request.GetCursorIndex() != 0) + return; + + for (const auto &c : m_interpreter.GetUserCommands()) + request.TryCompleteCurrentArg(c.first, c.second->GetHelp()); + } + protected: bool DoExecute(Args &command, CommandReturnObject &result) override { diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectCommands.h b/contrib/llvm-project/lldb/source/Commands/CommandObjectCommands.h index dcf02f3a7da9..f418e5ba779b 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectCommands.h +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectCommands.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CommandObjectCommands_h_ -#define liblldb_CommandObjectCommands_h_ +#ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTCOMMANDS_H +#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTCOMMANDS_H #include "lldb/Interpreter/CommandObjectMultiword.h" @@ -25,4 +25,4 @@ public: } // namespace lldb_private -#endif // liblldb_CommandObjectCommands_h_ +#endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTCOMMANDS_H diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectDisassemble.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectDisassemble.cpp index 63679e996e70..cf4d8ed04f81 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectDisassemble.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectDisassemble.cpp @@ -1,4 +1,4 @@ -//===-- CommandObjectDisassemble.cpp ----------------------------*- C++ -*-===// +//===-- CommandObjectDisassemble.cpp --------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -21,8 +21,9 @@ #include "lldb/Target/StackFrame.h" #include "lldb/Target/Target.h" -#define DEFAULT_DISASM_BYTE_SIZE 32 -#define DEFAULT_DISASM_NUM_INS 4 +static constexpr unsigned default_disasm_byte_size = 32; +static constexpr unsigned default_disasm_num_ins = 4; +static constexpr unsigned large_function_threshold = 8000; using namespace lldb; using namespace lldb_private; @@ -83,7 +84,7 @@ Status CommandObjectDisassemble::CommandOptions::SetOptionValue( } break; case 'n': - func_name.assign(option_arg); + func_name.assign(std::string(option_arg)); some_location_specified = true; break; @@ -101,7 +102,7 @@ Status CommandObjectDisassemble::CommandOptions::SetOptionValue( break; case 'P': - plugin_name.assign(option_arg); + plugin_name.assign(std::string(option_arg)); break; case 'F': { @@ -111,7 +112,7 @@ Status CommandObjectDisassemble::CommandOptions::SetOptionValue( llvm::Triple::x86 || target_sp->GetArchitecture().GetTriple().getArch() == llvm::Triple::x86_64)) { - flavor_string.assign(option_arg); + flavor_string.assign(std::string(option_arg)); } else error.SetErrorStringWithFormat("Disassembler flavors are currently only " "supported for x86 and x86_64 targets."); @@ -143,6 +144,10 @@ Status CommandObjectDisassemble::CommandOptions::SetOptionValue( } } break; + case '\x01': + force = true; + break; + default: llvm_unreachable("Unimplemented option"); } @@ -186,6 +191,7 @@ void CommandObjectDisassemble::CommandOptions::OptionParsingStarting( arch.Clear(); some_location_specified = false; + force = false; } Status CommandObjectDisassemble::CommandOptions::OptionParsingFinished( @@ -214,6 +220,194 @@ CommandObjectDisassemble::CommandObjectDisassemble( CommandObjectDisassemble::~CommandObjectDisassemble() = default; +llvm::Error CommandObjectDisassemble::CheckRangeSize(const AddressRange &range, + llvm::StringRef what) { + if (m_options.num_instructions > 0 || m_options.force || + range.GetByteSize() < large_function_threshold) + return llvm::Error::success(); + StreamString msg; + msg << "Not disassembling " << what << " because it is very large "; + range.Dump(&msg, &GetSelectedTarget(), Address::DumpStyleLoadAddress, + Address::DumpStyleFileAddress); + msg << ". To disassemble specify an instruction count limit, start/stop " + "addresses or use the --force option."; + return llvm::createStringError(llvm::inconvertibleErrorCode(), + msg.GetString()); +} + +llvm::Expected<std::vector<AddressRange>> +CommandObjectDisassemble::GetContainingAddressRanges() { + std::vector<AddressRange> ranges; + const auto &get_range = [&](Address addr) { + ModuleSP module_sp(addr.GetModule()); + SymbolContext sc; + bool resolve_tail_call_address = true; + addr.GetModule()->ResolveSymbolContextForAddress( + addr, eSymbolContextEverything, sc, resolve_tail_call_address); + if (sc.function || sc.symbol) { + AddressRange range; + sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, 0, + false, range); + ranges.push_back(range); + } + }; + + Target &target = GetSelectedTarget(); + if (!target.GetSectionLoadList().IsEmpty()) { + Address symbol_containing_address; + if (target.GetSectionLoadList().ResolveLoadAddress( + m_options.symbol_containing_addr, symbol_containing_address)) { + get_range(symbol_containing_address); + } + } else { + for (lldb::ModuleSP module_sp : target.GetImages().Modules()) { + Address file_address; + if (module_sp->ResolveFileAddress(m_options.symbol_containing_addr, + file_address)) { + get_range(file_address); + } + } + } + + if (ranges.empty()) { + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "Could not find function bounds for address 0x%" PRIx64, + m_options.symbol_containing_addr); + } + + if (llvm::Error err = CheckRangeSize(ranges[0], "the function")) + return std::move(err); + return ranges; +} + +llvm::Expected<std::vector<AddressRange>> +CommandObjectDisassemble::GetCurrentFunctionRanges() { + StackFrame *frame = m_exe_ctx.GetFramePtr(); + if (!frame) { + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Cannot disassemble around the current " + "function without a selected frame.\n"); + } + SymbolContext sc( + frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol)); + AddressRange range; + if (sc.function) + range = sc.function->GetAddressRange(); + else if (sc.symbol && sc.symbol->ValueIsAddress()) { + range = {sc.symbol->GetAddress(), sc.symbol->GetByteSize()}; + } else + range = {frame->GetFrameCodeAddress(), default_disasm_byte_size}; + + if (llvm::Error err = CheckRangeSize(range, "the current function")) + return std::move(err); + return std::vector<AddressRange>{range}; +} + +llvm::Expected<std::vector<AddressRange>> +CommandObjectDisassemble::GetCurrentLineRanges() { + StackFrame *frame = m_exe_ctx.GetFramePtr(); + if (!frame) { + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Cannot disassemble around the current " + "line without a selected frame.\n"); + } + + LineEntry pc_line_entry( + frame->GetSymbolContext(eSymbolContextLineEntry).line_entry); + if (pc_line_entry.IsValid()) + return std::vector<AddressRange>{pc_line_entry.range}; + + // No line entry, so just disassemble around the current pc + m_options.show_mixed = false; + return GetPCRanges(); +} + +llvm::Expected<std::vector<AddressRange>> +CommandObjectDisassemble::GetNameRanges(CommandReturnObject &result) { + ConstString name(m_options.func_name.c_str()); + const bool include_symbols = true; + const bool include_inlines = true; + + // Find functions matching the given name. + SymbolContextList sc_list; + GetSelectedTarget().GetImages().FindFunctions( + name, eFunctionNameTypeAuto, include_symbols, include_inlines, sc_list); + + std::vector<AddressRange> ranges; + llvm::Error range_errs = llvm::Error::success(); + AddressRange range; + const uint32_t scope = + eSymbolContextBlock | eSymbolContextFunction | eSymbolContextSymbol; + const bool use_inline_block_range = true; + for (SymbolContext sc : sc_list.SymbolContexts()) { + for (uint32_t range_idx = 0; + sc.GetAddressRange(scope, range_idx, use_inline_block_range, range); + ++range_idx) { + if (llvm::Error err = CheckRangeSize(range, "a range")) + range_errs = joinErrors(std::move(range_errs), std::move(err)); + else + ranges.push_back(range); + } + } + if (ranges.empty()) { + if (range_errs) + return std::move(range_errs); + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Unable to find symbol with name '%s'.\n", + name.GetCString()); + } + if (range_errs) + result.AppendWarning(toString(std::move(range_errs))); + return ranges; +} + +llvm::Expected<std::vector<AddressRange>> +CommandObjectDisassemble::GetPCRanges() { + StackFrame *frame = m_exe_ctx.GetFramePtr(); + if (!frame) { + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Cannot disassemble around the current " + "PC without a selected frame.\n"); + } + + if (m_options.num_instructions == 0) { + // Disassembling at the PC always disassembles some number of + // instructions (not the whole function). + m_options.num_instructions = default_disasm_num_ins; + } + return std::vector<AddressRange>{{frame->GetFrameCodeAddress(), 0}}; +} + +llvm::Expected<std::vector<AddressRange>> +CommandObjectDisassemble::GetStartEndAddressRanges() { + addr_t size = 0; + if (m_options.end_addr != LLDB_INVALID_ADDRESS) { + if (m_options.end_addr <= m_options.start_addr) { + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "End address before start address."); + } + size = m_options.end_addr - m_options.start_addr; + } + return std::vector<AddressRange>{{Address(m_options.start_addr), size}}; +} + +llvm::Expected<std::vector<AddressRange>> +CommandObjectDisassemble::GetRangesForSelectedMode( + CommandReturnObject &result) { + if (m_options.symbol_containing_addr != LLDB_INVALID_ADDRESS) + return CommandObjectDisassemble::GetContainingAddressRanges(); + if (m_options.current_function) + return CommandObjectDisassemble::GetCurrentFunctionRanges(); + if (m_options.frame_line) + return CommandObjectDisassemble::GetCurrentLineRanges(); + if (!m_options.func_name.empty()) + return CommandObjectDisassemble::GetNameRanges(result); + if (m_options.start_addr != LLDB_INVALID_ADDRESS) + return CommandObjectDisassemble::GetStartEndAddressRanges(); + return CommandObjectDisassemble::GetPCRanges(); +} + bool CommandObjectDisassemble::DoExecute(Args &command, CommandReturnObject &result) { Target *target = &GetSelectedTarget(); @@ -281,238 +475,44 @@ bool CommandObjectDisassemble::DoExecute(Args &command, if (m_options.raw) options |= Disassembler::eOptionRawOuput; - if (!m_options.func_name.empty()) { - ConstString name(m_options.func_name.c_str()); + llvm::Expected<std::vector<AddressRange>> ranges = + GetRangesForSelectedMode(result); + if (!ranges) { + result.AppendError(toString(ranges.takeError())); + result.SetStatus(eReturnStatusFailed); + return result.Succeeded(); + } + bool print_sc_header = ranges->size() > 1; + for (AddressRange cur_range : *ranges) { + Disassembler::Limit limit; + if (m_options.num_instructions == 0) { + limit = {Disassembler::Limit::Bytes, cur_range.GetByteSize()}; + if (limit.value == 0) + limit.value = default_disasm_byte_size; + } else { + limit = {Disassembler::Limit::Instructions, m_options.num_instructions}; + } if (Disassembler::Disassemble( GetDebugger(), m_options.arch, plugin_name, flavor_string, - m_exe_ctx, name, - nullptr, // Module * - m_options.num_instructions, m_options.show_mixed, + m_exe_ctx, cur_range.GetBaseAddress(), limit, m_options.show_mixed, m_options.show_mixed ? m_options.num_lines_context : 0, options, result.GetOutputStream())) { result.SetStatus(eReturnStatusSuccessFinishResult); } else { - result.AppendErrorWithFormat("Unable to find symbol with name '%s'.\n", - name.GetCString()); - result.SetStatus(eReturnStatusFailed); - } - } else { - std::vector<AddressRange> ranges; - AddressRange range; - StackFrame *frame = m_exe_ctx.GetFramePtr(); - if (m_options.frame_line) { - if (frame == nullptr) { - result.AppendError("Cannot disassemble around the current line without " - "a selected frame.\n"); - result.SetStatus(eReturnStatusFailed); - return false; - } - LineEntry pc_line_entry( - frame->GetSymbolContext(eSymbolContextLineEntry).line_entry); - if (pc_line_entry.IsValid()) { - range = pc_line_entry.range; - } else { - m_options.at_pc = - true; // No line entry, so just disassemble around the current pc - m_options.show_mixed = false; - } - } else if (m_options.current_function) { - if (frame == nullptr) { - result.AppendError("Cannot disassemble around the current function " - "without a selected frame.\n"); - result.SetStatus(eReturnStatusFailed); - return false; - } - Symbol *symbol = frame->GetSymbolContext(eSymbolContextSymbol).symbol; - if (symbol) { - range.GetBaseAddress() = symbol->GetAddress(); - range.SetByteSize(symbol->GetByteSize()); - } - } - - // Did the "m_options.frame_line" find a valid range already? If so skip - // the rest... - if (range.GetByteSize() == 0) { - if (m_options.at_pc) { - if (frame == nullptr) { - result.AppendError("Cannot disassemble around the current PC without " - "a selected frame.\n"); - result.SetStatus(eReturnStatusFailed); - return false; - } - range.GetBaseAddress() = frame->GetFrameCodeAddress(); - if (m_options.num_instructions == 0) { - // Disassembling at the PC always disassembles some number of - // instructions (not the whole function). - m_options.num_instructions = DEFAULT_DISASM_NUM_INS; - } - ranges.push_back(range); + if (m_options.symbol_containing_addr != LLDB_INVALID_ADDRESS) { + result.AppendErrorWithFormat( + "Failed to disassemble memory in function at 0x%8.8" PRIx64 ".\n", + m_options.symbol_containing_addr); } else { - range.GetBaseAddress().SetOffset(m_options.start_addr); - if (range.GetBaseAddress().IsValid()) { - if (m_options.end_addr != LLDB_INVALID_ADDRESS) { - if (m_options.end_addr <= m_options.start_addr) { - result.AppendErrorWithFormat( - "End address before start address.\n"); - result.SetStatus(eReturnStatusFailed); - return false; - } - range.SetByteSize(m_options.end_addr - m_options.start_addr); - } - ranges.push_back(range); - } else { - if (m_options.symbol_containing_addr != LLDB_INVALID_ADDRESS && - target) { - if (!target->GetSectionLoadList().IsEmpty()) { - bool failed = false; - Address symbol_containing_address; - if (target->GetSectionLoadList().ResolveLoadAddress( - m_options.symbol_containing_addr, - symbol_containing_address)) { - ModuleSP module_sp(symbol_containing_address.GetModule()); - SymbolContext sc; - bool resolve_tail_call_address = true; // PC can be one past the - // address range of the - // function. - module_sp->ResolveSymbolContextForAddress( - symbol_containing_address, eSymbolContextEverything, sc, - resolve_tail_call_address); - if (sc.function || sc.symbol) { - sc.GetAddressRange(eSymbolContextFunction | - eSymbolContextSymbol, - 0, false, range); - } else { - failed = true; - } - } else { - failed = true; - } - if (failed) { - result.AppendErrorWithFormat( - "Could not find function bounds for address 0x%" PRIx64 - "\n", - m_options.symbol_containing_addr); - result.SetStatus(eReturnStatusFailed); - return false; - } - ranges.push_back(range); - } else { - for (lldb::ModuleSP module_sp : target->GetImages().Modules()) { - lldb::addr_t file_addr = m_options.symbol_containing_addr; - Address file_address; - if (module_sp->ResolveFileAddress(file_addr, file_address)) { - SymbolContext sc; - bool resolve_tail_call_address = true; // PC can be one past - // the address range of - // the function. - module_sp->ResolveSymbolContextForAddress( - file_address, eSymbolContextEverything, sc, - resolve_tail_call_address); - if (sc.function || sc.symbol) { - sc.GetAddressRange(eSymbolContextFunction | - eSymbolContextSymbol, - 0, false, range); - ranges.push_back(range); - } - } - } - } - } - } - } - } else - ranges.push_back(range); - - if (m_options.num_instructions != 0) { - if (ranges.empty()) { - // The default action is to disassemble the current frame function. - if (frame) { - SymbolContext sc(frame->GetSymbolContext(eSymbolContextFunction | - eSymbolContextSymbol)); - if (sc.function) - range.GetBaseAddress() = - sc.function->GetAddressRange().GetBaseAddress(); - else if (sc.symbol && sc.symbol->ValueIsAddress()) - range.GetBaseAddress() = sc.symbol->GetAddress(); - else - range.GetBaseAddress() = frame->GetFrameCodeAddress(); - } - - if (!range.GetBaseAddress().IsValid()) { - result.AppendError("invalid frame"); - result.SetStatus(eReturnStatusFailed); - return false; - } - } - - bool print_sc_header = ranges.size() > 1; - for (AddressRange cur_range : ranges) { - if (Disassembler::Disassemble( - GetDebugger(), m_options.arch, plugin_name, flavor_string, - m_exe_ctx, cur_range.GetBaseAddress(), - m_options.num_instructions, m_options.show_mixed, - m_options.show_mixed ? m_options.num_lines_context : 0, options, - result.GetOutputStream())) { - result.SetStatus(eReturnStatusSuccessFinishResult); - } else { - if (m_options.start_addr != LLDB_INVALID_ADDRESS) - result.AppendErrorWithFormat( - "Failed to disassemble memory at 0x%8.8" PRIx64 ".\n", - m_options.start_addr); - else if (m_options.symbol_containing_addr != LLDB_INVALID_ADDRESS) - result.AppendErrorWithFormat( - "Failed to disassemble memory in function at 0x%8.8" PRIx64 - ".\n", - m_options.symbol_containing_addr); - result.SetStatus(eReturnStatusFailed); - } - } - if (print_sc_header) - result.AppendMessage("\n"); - } else { - if (ranges.empty()) { - // The default action is to disassemble the current frame function. - if (frame) { - SymbolContext sc(frame->GetSymbolContext(eSymbolContextFunction | - eSymbolContextSymbol)); - if (sc.function) - range = sc.function->GetAddressRange(); - else if (sc.symbol && sc.symbol->ValueIsAddress()) { - range.GetBaseAddress() = sc.symbol->GetAddress(); - range.SetByteSize(sc.symbol->GetByteSize()); - } else - range.GetBaseAddress() = frame->GetFrameCodeAddress(); - } else { - result.AppendError("invalid frame"); - result.SetStatus(eReturnStatusFailed); - return false; - } - ranges.push_back(range); - } - - bool print_sc_header = ranges.size() > 1; - for (AddressRange cur_range : ranges) { - if (cur_range.GetByteSize() == 0) - cur_range.SetByteSize(DEFAULT_DISASM_BYTE_SIZE); - - if (Disassembler::Disassemble( - GetDebugger(), m_options.arch, plugin_name, flavor_string, - m_exe_ctx, cur_range, m_options.num_instructions, - m_options.show_mixed, - m_options.show_mixed ? m_options.num_lines_context : 0, options, - result.GetOutputStream())) { - result.SetStatus(eReturnStatusSuccessFinishResult); - } else { - result.AppendErrorWithFormat( - "Failed to disassemble memory at 0x%8.8" PRIx64 ".\n", - cur_range.GetBaseAddress().GetLoadAddress(target)); - result.SetStatus(eReturnStatusFailed); - } - if (print_sc_header) - result.AppendMessage("\n"); + result.AppendErrorWithFormat( + "Failed to disassemble memory at 0x%8.8" PRIx64 ".\n", + cur_range.GetBaseAddress().GetLoadAddress(target)); } + result.SetStatus(eReturnStatusFailed); } + if (print_sc_header) + result.GetOutputStream() << "\n"; } return result.Succeeded(); diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectDisassemble.h b/contrib/llvm-project/lldb/source/Commands/CommandObjectDisassemble.h index 70193e914c7f..340bf648de17 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectDisassemble.h +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectDisassemble.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CommandObjectDisassemble_h_ -#define liblldb_CommandObjectDisassemble_h_ +#ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTDISASSEMBLE_H +#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTDISASSEMBLE_H #include "lldb/Interpreter/CommandObject.h" #include "lldb/Interpreter/Options.h" @@ -62,6 +62,7 @@ public: // "at_pc". This should be set // in SetOptionValue if anything the selects a location is set. lldb::addr_t symbol_containing_addr; + bool force = false; }; CommandObjectDisassemble(CommandInterpreter &interpreter); @@ -73,9 +74,22 @@ public: protected: bool DoExecute(Args &command, CommandReturnObject &result) override; + llvm::Expected<std::vector<AddressRange>> + GetRangesForSelectedMode(CommandReturnObject &result); + + llvm::Expected<std::vector<AddressRange>> GetContainingAddressRanges(); + llvm::Expected<std::vector<AddressRange>> GetCurrentFunctionRanges(); + llvm::Expected<std::vector<AddressRange>> GetCurrentLineRanges(); + llvm::Expected<std::vector<AddressRange>> + GetNameRanges(CommandReturnObject &result); + llvm::Expected<std::vector<AddressRange>> GetPCRanges(); + llvm::Expected<std::vector<AddressRange>> GetStartEndAddressRanges(); + + llvm::Error CheckRangeSize(const AddressRange &range, llvm::StringRef what); + CommandOptions m_options; }; } // namespace lldb_private -#endif // liblldb_CommandObjectDisassemble_h_ +#endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTDISASSEMBLE_H diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectExpression.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectExpression.cpp index db90dde98eff..b23adb087b49 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectExpression.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectExpression.cpp @@ -1,4 +1,4 @@ -//===-- CommandObjectExpression.cpp -----------------------------*- C++ -*-===// +//===-- CommandObjectExpression.cpp ---------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -311,7 +311,12 @@ void CommandObjectExpression::HandleCompletion(CompletionRequest &request) { target = &GetDummyTarget(); unsigned cursor_pos = request.GetRawCursorPos(); - llvm::StringRef code = request.GetRawLine(); + // Get the full user input including the suffix. The suffix is necessary + // as OptionsWithRaw will use it to detect if the cursor is cursor is in the + // argument part of in the raw input part of the arguments. If we cut of + // of the suffix then "expr -arg[cursor] --" would interpret the "-arg" as + // the raw input (as the "--" is hidden in the suffix). + llvm::StringRef code = request.GetRawLineWithUnusedSuffix(); const std::size_t original_code_size = code.size(); @@ -357,29 +362,13 @@ CanBeUsedForElementCountPrinting(ValueObject &valobj) { return Status(); } -bool CommandObjectExpression::EvaluateExpression(llvm::StringRef expr, - Stream *output_stream, - Stream *error_stream, - CommandReturnObject *result) { - // Don't use m_exe_ctx as this might be called asynchronously after the - // command object DoExecute has finished when doing multi-line expression - // that use an input reader... - ExecutionContext exe_ctx(m_interpreter.GetExecutionContext()); - - Target *target = exe_ctx.GetTargetPtr(); - - if (!target) - target = &GetDummyTarget(); - - lldb::ValueObjectSP result_valobj_sp; - bool keep_in_memory = true; - StackFrame *frame = exe_ctx.GetFramePtr(); - +EvaluateExpressionOptions +CommandObjectExpression::GetEvalOptions(const Target &target) { EvaluateExpressionOptions options; options.SetCoerceToId(m_varobj_options.use_objc); options.SetUnwindOnError(m_command_options.unwind_on_error); options.SetIgnoreBreakpoints(m_command_options.ignore_breakpoints); - options.SetKeepInMemory(keep_in_memory); + options.SetKeepInMemory(true); options.SetUseDynamic(m_varobj_options.use_dynamic); options.SetTryAllThreads(m_command_options.try_all_threads); options.SetDebug(m_command_options.debug); @@ -391,11 +380,12 @@ bool CommandObjectExpression::EvaluateExpression(llvm::StringRef expr, bool auto_apply_fixits; if (m_command_options.auto_apply_fixits == eLazyBoolCalculate) - auto_apply_fixits = target->GetEnableAutoApplyFixIts(); + auto_apply_fixits = target.GetEnableAutoApplyFixIts(); else auto_apply_fixits = m_command_options.auto_apply_fixits == eLazyBoolYes; options.SetAutoApplyFixIts(auto_apply_fixits); + options.SetRetriesWithFixIts(target.GetNumberOfRetriesWithFixits()); if (m_command_options.top_level) options.SetExecutionPolicy(eExecutionPolicyTopLevel); @@ -410,17 +400,36 @@ bool CommandObjectExpression::EvaluateExpression(llvm::StringRef expr, options.SetTimeout(std::chrono::microseconds(m_command_options.timeout)); else options.SetTimeout(llvm::None); + return options; +} +bool CommandObjectExpression::EvaluateExpression(llvm::StringRef expr, + Stream &output_stream, + Stream &error_stream, + CommandReturnObject &result) { + // Don't use m_exe_ctx as this might be called asynchronously after the + // command object DoExecute has finished when doing multi-line expression + // that use an input reader... + ExecutionContext exe_ctx(m_interpreter.GetExecutionContext()); + + Target *target = exe_ctx.GetTargetPtr(); + + if (!target) + target = &GetDummyTarget(); + + lldb::ValueObjectSP result_valobj_sp; + StackFrame *frame = exe_ctx.GetFramePtr(); + + const EvaluateExpressionOptions options = GetEvalOptions(*target); ExpressionResults success = target->EvaluateExpression( expr, frame, result_valobj_sp, options, &m_fixed_expression); // We only tell you about the FixIt if we applied it. The compiler errors // will suggest the FixIt if it parsed. - if (error_stream && !m_fixed_expression.empty() && - target->GetEnableNotifyAboutFixIts()) { + if (!m_fixed_expression.empty() && target->GetEnableNotifyAboutFixIts()) { if (success == eExpressionCompleted) - error_stream->Printf(" Fix-it applied, fixed expression was: \n %s\n", - m_fixed_expression.c_str()); + error_stream.Printf(" Fix-it applied, fixed expression was: \n %s\n", + m_fixed_expression.c_str()); } if (result_valobj_sp) { @@ -434,10 +443,10 @@ bool CommandObjectExpression::EvaluateExpression(llvm::StringRef expr, if (m_varobj_options.elem_count > 0) { Status error(CanBeUsedForElementCountPrinting(*result_valobj_sp)); if (error.Fail()) { - result->AppendErrorWithFormat( + result.AppendErrorWithFormat( "expression cannot be used with --element-count %s\n", error.AsCString("")); - result->SetStatus(eReturnStatusFailed); + result.SetStatus(eReturnStatusFailed); return false; } } @@ -447,41 +456,39 @@ bool CommandObjectExpression::EvaluateExpression(llvm::StringRef expr, options.SetVariableFormatDisplayLanguage( result_valobj_sp->GetPreferredDisplayLanguage()); - result_valobj_sp->Dump(*output_stream, options); + result_valobj_sp->Dump(output_stream, options); - if (result) - result->SetStatus(eReturnStatusSuccessFinishResult); + result.SetStatus(eReturnStatusSuccessFinishResult); } } else { if (result_valobj_sp->GetError().GetError() == UserExpression::kNoResult) { if (format != eFormatVoid && GetDebugger().GetNotifyVoid()) { - error_stream->PutCString("(void)\n"); + error_stream.PutCString("(void)\n"); } - if (result) - result->SetStatus(eReturnStatusSuccessFinishResult); + result.SetStatus(eReturnStatusSuccessFinishResult); } else { const char *error_cstr = result_valobj_sp->GetError().AsCString(); if (error_cstr && error_cstr[0]) { const size_t error_cstr_len = strlen(error_cstr); const bool ends_with_newline = error_cstr[error_cstr_len - 1] == '\n'; if (strstr(error_cstr, "error:") != error_cstr) - error_stream->PutCString("error: "); - error_stream->Write(error_cstr, error_cstr_len); + error_stream.PutCString("error: "); + error_stream.Write(error_cstr, error_cstr_len); if (!ends_with_newline) - error_stream->EOL(); + error_stream.EOL(); } else { - error_stream->PutCString("error: unknown error\n"); + error_stream.PutCString("error: unknown error\n"); } - if (result) - result->SetStatus(eReturnStatusFailed); + result.SetStatus(eReturnStatusFailed); } } } - return true; + return (success != eExpressionSetupError && + success != eExpressionParseError); } void CommandObjectExpression::IOHandlerInputComplete(IOHandler &io_handler, @@ -493,7 +500,9 @@ void CommandObjectExpression::IOHandlerInputComplete(IOHandler &io_handler, StreamFileSP output_sp = io_handler.GetOutputStreamFileSP(); StreamFileSP error_sp = io_handler.GetErrorStreamFileSP(); - EvaluateExpression(line.c_str(), output_sp.get(), error_sp.get()); + CommandReturnObject return_obj( + GetCommandInterpreter().GetDebugger().GetUseColor()); + EvaluateExpression(line.c_str(), *output_sp, *error_sp, return_obj); if (output_sp) output_sp->Flush(); if (error_sp) @@ -535,7 +544,7 @@ void CommandObjectExpression::GetMultilineExpression() { "Enter expressions, then terminate with an empty line to evaluate:\n"); output_sp->Flush(); } - debugger.PushIOHandler(io_handler_sp); + debugger.RunIOHandlerAsync(io_handler_sp); } static EvaluateExpressionOptions @@ -622,10 +631,8 @@ bool CommandObjectExpression::DoExecute(llvm::StringRef command, } IOHandlerSP io_handler_sp(repl_sp->GetIOHandler()); - io_handler_sp->SetIsDone(false); - - debugger.PushIOHandler(io_handler_sp); + debugger.RunIOHandlerAsync(io_handler_sp); } else { repl_error.SetErrorStringWithFormat( "Couldn't create a REPL for %s", @@ -643,8 +650,8 @@ bool CommandObjectExpression::DoExecute(llvm::StringRef command, } Target &target = GetSelectedOrDummyTarget(); - if (EvaluateExpression(expr, &(result.GetOutputStream()), - &(result.GetErrorStream()), &result)) { + if (EvaluateExpression(expr, result.GetOutputStream(), + result.GetErrorStream(), result)) { if (!m_fixed_expression.empty() && target.GetEnableNotifyAboutFixIts()) { CommandHistory &history = m_interpreter.GetCommandHistory(); @@ -654,7 +661,7 @@ bool CommandObjectExpression::DoExecute(llvm::StringRef command, std::string fixed_command("expression "); if (args.HasArgs()) { // Add in any options that might have been in the original command: - fixed_command.append(args.GetArgStringWithDelimiter()); + fixed_command.append(std::string(args.GetArgStringWithDelimiter())); fixed_command.append(m_fixed_expression); } else fixed_command.append(m_fixed_expression); diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectExpression.h b/contrib/llvm-project/lldb/source/Commands/CommandObjectExpression.h index de159863b43a..1e59cbc14528 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectExpression.h +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectExpression.h @@ -6,15 +6,17 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CommandObjectExpression_h_ -#define liblldb_CommandObjectExpression_h_ +#ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTEXPRESSION_H +#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTEXPRESSION_H #include "lldb/Core/IOHandler.h" #include "lldb/Interpreter/CommandObject.h" #include "lldb/Interpreter/OptionGroupBoolean.h" #include "lldb/Interpreter/OptionGroupFormat.h" #include "lldb/Interpreter/OptionGroupValueObjectDisplay.h" +#include "lldb/Target/Target.h" #include "lldb/lldb-private-enumerations.h" + namespace lldb_private { class CommandObjectExpression : public CommandObjectRaw, @@ -65,9 +67,22 @@ protected: bool DoExecute(llvm::StringRef command, CommandReturnObject &result) override; - bool EvaluateExpression(llvm::StringRef expr, Stream *output_stream, - Stream *error_stream, - CommandReturnObject *result = nullptr); + /// Return the appropriate expression options used for evaluating the + /// expression in the given target. + EvaluateExpressionOptions GetEvalOptions(const Target &target); + + /// Evaluates the given expression. + /// \param output_stream The stream to which the evaluation result will be + /// printed. + /// \param error_stream Contains error messages that should be displayed to + /// the user in case the evaluation fails. + /// \param result A CommandReturnObject which status will be set to the + /// appropriate value depending on evaluation success and + /// whether the expression produced any result. + /// \return Returns true iff the expression was successfully evaluated, + /// executed and the result could be printed to the output stream. + bool EvaluateExpression(llvm::StringRef expr, Stream &output_stream, + Stream &error_stream, CommandReturnObject &result); void GetMultilineExpression(); @@ -83,4 +98,4 @@ protected: } // namespace lldb_private -#endif // liblldb_CommandObjectExpression_h_ +#endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTEXPRESSION_H diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectFrame.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectFrame.cpp index 50d5c751de5c..6ebad9b5c488 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectFrame.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectFrame.cpp @@ -1,4 +1,4 @@ -//===-- CommandObjectFrame.cpp ----------------------------------*- C++ -*-===// +//===-- CommandObjectFrame.cpp --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -12,7 +12,6 @@ #include "lldb/DataFormatters/ValueObjectPrinter.h" #include "lldb/Host/Config.h" #include "lldb/Host/OptionParser.h" -#include "lldb/Host/StringConvert.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" #include "lldb/Interpreter/OptionGroupFormat.h" @@ -172,8 +171,7 @@ protected: Stream &stream) -> bool { const ValueObject::GetExpressionPathFormat format = ValueObject:: GetExpressionPathFormat::eGetExpressionPathFormatHonorPointers; - const bool qualify_cxx_base_classes = false; - valobj_sp->GetExpressionPath(stream, qualify_cxx_base_classes, format); + valobj_sp->GetExpressionPath(stream, format); stream.PutCString(" ="); return true; }; @@ -187,7 +185,6 @@ protected: return true; } -protected: CommandOptions m_options; }; @@ -291,6 +288,22 @@ public: ~CommandObjectFrameSelect() override = default; + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { + if (!m_exe_ctx.HasProcessScope() || request.GetCursorIndex() != 0) + return; + + lldb::ThreadSP thread_sp = m_exe_ctx.GetThreadSP(); + const uint32_t frame_num = thread_sp->GetStackFrameCount(); + for (uint32_t i = 0; i < frame_num; ++i) { + lldb::StackFrameSP frame_sp = thread_sp->GetStackFrameAtIndex(i); + StreamString strm; + frame_sp->Dump(&strm, false, true); + request.TryCompleteCurrentArg(std::to_string(i), strm.GetString()); + } + } + Options *GetOptions() override { return &m_options; } protected: @@ -380,7 +393,6 @@ protected: return result.Succeeded(); } -protected: CommandOptions m_options; }; @@ -715,7 +727,6 @@ protected: return res; } -protected: OptionGroupOptions m_option_group; OptionGroupVariable m_option_variable; OptionGroupFormat m_option_format; @@ -747,7 +758,7 @@ private: m_module = std::string(option_arg); break; case 'n': - m_function = std::string(option_arg); + m_symbols.push_back(std::string(option_arg)); break; case 'x': m_regex = true; @@ -761,7 +772,7 @@ private: void OptionParsingStarting(ExecutionContext *execution_context) override { m_module = ""; - m_function = ""; + m_symbols.clear(); m_class_name = ""; m_regex = false; } @@ -773,7 +784,7 @@ private: // Instance variables to hold the values for command options. std::string m_class_name; std::string m_module; - std::string m_function; + std::vector<std::string> m_symbols; bool m_regex; }; @@ -855,9 +866,18 @@ bool CommandObjectFrameRecognizerAdd::DoExecute(Args &command, return false; } - if (m_options.m_function.empty()) { - result.AppendErrorWithFormat("%s needs a function name (-n argument).\n", - m_cmd_name.c_str()); + if (m_options.m_symbols.empty()) { + result.AppendErrorWithFormat( + "%s needs at least one symbol name (-n argument).\n", + m_cmd_name.c_str()); + result.SetStatus(eReturnStatusFailed); + return false; + } + + if (m_options.m_regex && m_options.m_symbols.size() > 1) { + result.AppendErrorWithFormat( + "%s needs only one symbol regular expression (-n argument).\n", + m_cmd_name.c_str()); result.SetStatus(eReturnStatusFailed); return false; } @@ -877,12 +897,13 @@ bool CommandObjectFrameRecognizerAdd::DoExecute(Args &command, auto module = RegularExpressionSP(new RegularExpression(m_options.m_module)); auto func = - RegularExpressionSP(new RegularExpression(m_options.m_function)); + RegularExpressionSP(new RegularExpression(m_options.m_symbols.front())); StackFrameRecognizerManager::AddRecognizer(recognizer_sp, module, func); } else { auto module = ConstString(m_options.m_module); - auto func = ConstString(m_options.m_function); - StackFrameRecognizerManager::AddRecognizer(recognizer_sp, module, func); + std::vector<ConstString> symbols(m_options.m_symbols.begin(), + m_options.m_symbols.end()); + StackFrameRecognizerManager::AddRecognizer(recognizer_sp, module, symbols); } #endif @@ -914,6 +935,33 @@ public: ~CommandObjectFrameRecognizerDelete() override = default; + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { + if (request.GetCursorIndex() != 0) + return; + + StackFrameRecognizerManager::ForEach( + [&request](uint32_t rid, std::string rname, std::string module, + llvm::ArrayRef<lldb_private::ConstString> symbols, + bool regexp) { + StreamString strm; + if (rname.empty()) + rname = "(internal)"; + + strm << rname; + if (!module.empty()) + strm << ", module " << module; + if (!symbols.empty()) + for (auto &symbol : symbols) + strm << ", symbol " << symbol; + if (regexp) + strm << " (regexp)"; + + request.TryCompleteCurrentArg(std::to_string(rid), strm.GetString()); + }); + } + protected: bool DoExecute(Args &command, CommandReturnObject &result) override { if (command.GetArgumentCount() == 0) { @@ -937,8 +985,13 @@ protected: return false; } - uint32_t recognizer_id = - StringConvert::ToUInt32(command.GetArgumentAtIndex(0), 0, 0); + uint32_t recognizer_id; + if (!llvm::to_integer(command.GetArgumentAtIndex(0), recognizer_id)) { + result.AppendErrorWithFormat("'%s' is not a valid recognizer id.\n", + command.GetArgumentAtIndex(0)); + result.SetStatus(eReturnStatusFailed); + return false; + } StackFrameRecognizerManager::RemoveRecognizerWithID(recognizer_id); result.SetStatus(eReturnStatusSuccessFinishResult); @@ -959,14 +1012,26 @@ protected: bool DoExecute(Args &command, CommandReturnObject &result) override { bool any_printed = false; StackFrameRecognizerManager::ForEach( - [&result, &any_printed](uint32_t recognizer_id, std::string name, - std::string function, std::string symbol, - bool regexp) { - if (name == "") + [&result, &any_printed]( + uint32_t recognizer_id, std::string name, std::string module, + llvm::ArrayRef<ConstString> symbols, bool regexp) { + Stream &stream = result.GetOutputStream(); + + if (name.empty()) name = "(internal)"; - result.GetOutputStream().Printf( - "%d: %s, module %s, function %s%s\n", recognizer_id, name.c_str(), - function.c_str(), symbol.c_str(), regexp ? " (regexp)" : ""); + + stream << std::to_string(recognizer_id) << ": " << name; + if (!module.empty()) + stream << ", module " << module; + if (!symbols.empty()) + for (auto &symbol : symbols) + stream << ", symbol " << symbol; + if (regexp) + stream << " (regexp)"; + + stream.EOL(); + stream.Flush(); + any_printed = true; }); @@ -1006,6 +1071,15 @@ public: protected: bool DoExecute(Args &command, CommandReturnObject &result) override { + const char *frame_index_str = command.GetArgumentAtIndex(0); + uint32_t frame_index; + if (!llvm::to_integer(frame_index_str, frame_index)) { + result.AppendErrorWithFormat("'%s' is not a valid frame index.", + frame_index_str); + result.SetStatus(eReturnStatusFailed); + return false; + } + Process *process = m_exe_ctx.GetProcessPtr(); if (process == nullptr) { result.AppendError("no process"); @@ -1025,8 +1099,6 @@ protected: return false; } - uint32_t frame_index = - StringConvert::ToUInt32(command.GetArgumentAtIndex(0), 0, 0); StackFrameSP frame_sp = thread->GetStackFrameAtIndex(frame_index); if (!frame_sp) { result.AppendErrorWithFormat("no frame with index %u", frame_index); diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectFrame.h b/contrib/llvm-project/lldb/source/Commands/CommandObjectFrame.h index b2378f14290d..71cb94aa8f5a 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectFrame.h +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectFrame.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CommandObjectFrame_h_ -#define liblldb_CommandObjectFrame_h_ +#ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTFRAME_H +#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTFRAME_H #include "lldb/Interpreter/CommandObjectMultiword.h" @@ -24,4 +24,4 @@ public: } // namespace lldb_private -#endif // liblldb_CommandObjectFrame_h_ +#endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTFRAME_H diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectGUI.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectGUI.cpp index 67ddc68a169e..3f45a26de228 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectGUI.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectGUI.cpp @@ -1,4 +1,4 @@ -//===-- CommandObjectGUI.cpp ------------------------------------*- C++ -*-===// +//===-- CommandObjectGUI.cpp ----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -35,7 +35,7 @@ bool CommandObjectGUI::DoExecute(Args &args, CommandReturnObject &result) { input.GetIsInteractive()) { IOHandlerSP io_handler_sp(new IOHandlerCursesGUI(debugger)); if (io_handler_sp) - debugger.PushIOHandler(io_handler_sp); + debugger.RunIOHandlerAsync(io_handler_sp); result.SetStatus(eReturnStatusSuccessFinishResult); } else { result.AppendError("the gui command requires an interactive terminal."); @@ -47,7 +47,7 @@ bool CommandObjectGUI::DoExecute(Args &args, CommandReturnObject &result) { } return true; #else - result.AppendError("lldb was not build with gui support"); + result.AppendError("lldb was not built with gui support"); return false; #endif } diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectGUI.h b/contrib/llvm-project/lldb/source/Commands/CommandObjectGUI.h index a19aad18ec35..49bad49a957d 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectGUI.h +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectGUI.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CommandObjectGUI_h_ -#define liblldb_CommandObjectGUI_h_ +#ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTGUI_H +#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTGUI_H #include "lldb/Interpreter/CommandObject.h" @@ -27,4 +27,4 @@ protected: } // namespace lldb_private -#endif // liblldb_CommandObjectGUI_h_ +#endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTGUI_H diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectHelp.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectHelp.cpp index 6e908dc496a0..6dc1868a2aff 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectHelp.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectHelp.cpp @@ -1,4 +1,4 @@ -//===-- CommandObjectHelp.cpp -----------------------------------*- C++ -*-===// +//===-- CommandObjectHelp.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -107,7 +107,7 @@ bool CommandObjectHelp::DoExecute(Args &command, CommandReturnObject &result) { // object that corresponds to the help command entered. std::string sub_command; for (auto &entry : command.entries().drop_front()) { - sub_command = entry.ref(); + sub_command = std::string(entry.ref()); matches.Clear(); if (sub_cmd_obj->IsAlias()) sub_cmd_obj = diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectHelp.h b/contrib/llvm-project/lldb/source/Commands/CommandObjectHelp.h index 52a00ac79ff9..8f45db55666e 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectHelp.h +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectHelp.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CommandObjectHelp_h_ -#define liblldb_CommandObjectHelp_h_ +#ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTHELP_H +#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTHELP_H #include "lldb/Host/OptionParser.h" #include "lldb/Interpreter/CommandObject.h" @@ -84,4 +84,4 @@ private: } // namespace lldb_private -#endif // liblldb_CommandObjectHelp_h_ +#endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTHELP_H diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectLanguage.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectLanguage.cpp index 35ce6e3193e8..e6d22ec4ae40 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectLanguage.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectLanguage.cpp @@ -1,4 +1,4 @@ -//===-- CommandObjectLanguage.cpp -------------------------------*- C++ -*-===// +//===-- CommandObjectLanguage.cpp -----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectLanguage.h b/contrib/llvm-project/lldb/source/Commands/CommandObjectLanguage.h index 47079e219d03..7a280902a07e 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectLanguage.h +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectLanguage.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CommandObjectLanguage_h_ -#define liblldb_CommandObjectLanguage_h_ +#ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTLANGUAGE_H +#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTLANGUAGE_H #include "lldb/Interpreter/CommandObjectMultiword.h" @@ -23,4 +23,4 @@ protected: }; } // namespace lldb_private -#endif // liblldb_CommandObjectLanguage_h_ +#endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTLANGUAGE_H diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectLog.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectLog.cpp index 9bf0b30bc152..4016b07c91ed 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectLog.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectLog.cpp @@ -1,4 +1,4 @@ -//===-- CommandObjectLog.cpp ------------------------------------*- C++ -*-===// +//===-- CommandObjectLog.cpp ----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -156,7 +156,7 @@ protected: } // Store into a std::string since we're about to shift the channel off. - const std::string channel = args[0].ref(); + const std::string channel = std::string(args[0].ref()); args.Shift(); // Shift off the channel char log_file[PATH_MAX]; if (m_options.log_file) @@ -229,7 +229,7 @@ protected: return false; } - const std::string channel = args[0].ref(); + const std::string channel = std::string(args[0].ref()); args.Shift(); // Shift off the channel if (channel == "all") { Log::DisableAllLogChannels(); @@ -298,61 +298,170 @@ protected: } }; -class CommandObjectLogTimer : public CommandObjectParsed { +class CommandObjectLogTimerEnable : public CommandObjectParsed { public: // Constructors and Destructors - CommandObjectLogTimer(CommandInterpreter &interpreter) - : CommandObjectParsed(interpreter, "log timers", - "Enable, disable, dump, and reset LLDB internal " - "performance timers.", - "log timers < enable <depth> | disable | dump | " - "increment <bool> | reset >") {} + CommandObjectLogTimerEnable(CommandInterpreter &interpreter) + : CommandObjectParsed(interpreter, "log timers enable", + "enable LLDB internal performance timers", + "log timers enable <depth>") { + CommandArgumentEntry arg; + CommandArgumentData depth_arg; - ~CommandObjectLogTimer() override = default; + // Define the first (and only) variant of this arg. + depth_arg.arg_type = eArgTypeCount; + depth_arg.arg_repetition = eArgRepeatOptional; + + // There is only one variant this argument could be; put it into the + // argument entry. + arg.push_back(depth_arg); + + // Push the data for the first argument into the m_arguments vector. + m_arguments.push_back(arg); + } + + ~CommandObjectLogTimerEnable() override = default; + +protected: + bool DoExecute(Args &args, CommandReturnObject &result) override { + result.SetStatus(eReturnStatusFailed); + + if (args.GetArgumentCount() == 0) { + Timer::SetDisplayDepth(UINT32_MAX); + result.SetStatus(eReturnStatusSuccessFinishNoResult); + } else if (args.GetArgumentCount() == 1) { + uint32_t depth; + if (args[0].ref().consumeInteger(0, depth)) { + result.AppendError( + "Could not convert enable depth to an unsigned integer."); + } else { + Timer::SetDisplayDepth(depth); + result.SetStatus(eReturnStatusSuccessFinishNoResult); + } + } + + if (!result.Succeeded()) { + result.AppendError("Missing subcommand"); + result.AppendErrorWithFormat("Usage: %s\n", m_cmd_syntax.c_str()); + } + return result.Succeeded(); + } +}; + +class CommandObjectLogTimerDisable : public CommandObjectParsed { +public: + // Constructors and Destructors + CommandObjectLogTimerDisable(CommandInterpreter &interpreter) + : CommandObjectParsed(interpreter, "log timers disable", + "disable LLDB internal performance timers", + nullptr) {} + + ~CommandObjectLogTimerDisable() override = default; + +protected: + bool DoExecute(Args &args, CommandReturnObject &result) override { + Timer::DumpCategoryTimes(&result.GetOutputStream()); + Timer::SetDisplayDepth(0); + result.SetStatus(eReturnStatusSuccessFinishResult); + + if (!result.Succeeded()) { + result.AppendError("Missing subcommand"); + result.AppendErrorWithFormat("Usage: %s\n", m_cmd_syntax.c_str()); + } + return result.Succeeded(); + } +}; + +class CommandObjectLogTimerDump : public CommandObjectParsed { +public: + // Constructors and Destructors + CommandObjectLogTimerDump(CommandInterpreter &interpreter) + : CommandObjectParsed(interpreter, "log timers dump", + "dump LLDB internal performance timers", nullptr) {} + + ~CommandObjectLogTimerDump() override = default; + +protected: + bool DoExecute(Args &args, CommandReturnObject &result) override { + Timer::DumpCategoryTimes(&result.GetOutputStream()); + result.SetStatus(eReturnStatusSuccessFinishResult); + + if (!result.Succeeded()) { + result.AppendError("Missing subcommand"); + result.AppendErrorWithFormat("Usage: %s\n", m_cmd_syntax.c_str()); + } + return result.Succeeded(); + } +}; + +class CommandObjectLogTimerReset : public CommandObjectParsed { +public: + // Constructors and Destructors + CommandObjectLogTimerReset(CommandInterpreter &interpreter) + : CommandObjectParsed(interpreter, "log timers reset", + "reset LLDB internal performance timers", nullptr) { + } + + ~CommandObjectLogTimerReset() override = default; + +protected: + bool DoExecute(Args &args, CommandReturnObject &result) override { + Timer::ResetCategoryTimes(); + result.SetStatus(eReturnStatusSuccessFinishResult); + + if (!result.Succeeded()) { + result.AppendError("Missing subcommand"); + result.AppendErrorWithFormat("Usage: %s\n", m_cmd_syntax.c_str()); + } + return result.Succeeded(); + } +}; + +class CommandObjectLogTimerIncrement : public CommandObjectParsed { +public: + // Constructors and Destructors + CommandObjectLogTimerIncrement(CommandInterpreter &interpreter) + : CommandObjectParsed(interpreter, "log timers increment", + "increment LLDB internal performance timers", + "log timers increment <bool>") { + CommandArgumentEntry arg; + CommandArgumentData bool_arg; + + // Define the first (and only) variant of this arg. + bool_arg.arg_type = eArgTypeBoolean; + bool_arg.arg_repetition = eArgRepeatPlain; + + // There is only one variant this argument could be; put it into the + // argument entry. + arg.push_back(bool_arg); + + // Push the data for the first argument into the m_arguments vector. + m_arguments.push_back(arg); + } + + ~CommandObjectLogTimerIncrement() override = default; + + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { + request.TryCompleteCurrentArg("true"); + request.TryCompleteCurrentArg("false"); + } protected: bool DoExecute(Args &args, CommandReturnObject &result) override { result.SetStatus(eReturnStatusFailed); if (args.GetArgumentCount() == 1) { - auto sub_command = args[0].ref(); + bool success; + bool increment = + OptionArgParser::ToBoolean(args[0].ref(), false, &success); - if (sub_command.equals_lower("enable")) { - Timer::SetDisplayDepth(UINT32_MAX); + if (success) { + Timer::SetQuiet(!increment); result.SetStatus(eReturnStatusSuccessFinishNoResult); - } else if (sub_command.equals_lower("disable")) { - Timer::DumpCategoryTimes(&result.GetOutputStream()); - Timer::SetDisplayDepth(0); - result.SetStatus(eReturnStatusSuccessFinishResult); - } else if (sub_command.equals_lower("dump")) { - Timer::DumpCategoryTimes(&result.GetOutputStream()); - result.SetStatus(eReturnStatusSuccessFinishResult); - } else if (sub_command.equals_lower("reset")) { - Timer::ResetCategoryTimes(); - result.SetStatus(eReturnStatusSuccessFinishResult); - } - } else if (args.GetArgumentCount() == 2) { - auto sub_command = args[0].ref(); - auto param = args[1].ref(); - - if (sub_command.equals_lower("enable")) { - uint32_t depth; - if (param.consumeInteger(0, depth)) { - result.AppendError( - "Could not convert enable depth to an unsigned integer."); - } else { - Timer::SetDisplayDepth(depth); - result.SetStatus(eReturnStatusSuccessFinishNoResult); - } - } else if (sub_command.equals_lower("increment")) { - bool success; - bool increment = OptionArgParser::ToBoolean(param, false, &success); - if (success) { - Timer::SetQuiet(!increment); - result.SetStatus(eReturnStatusSuccessFinishNoResult); - } else - result.AppendError("Could not convert increment value to boolean."); - } + } else + result.AppendError("Could not convert increment value to boolean."); } if (!result.Succeeded()) { @@ -363,6 +472,30 @@ protected: } }; +class CommandObjectLogTimer : public CommandObjectMultiword { +public: + CommandObjectLogTimer(CommandInterpreter &interpreter) + : CommandObjectMultiword(interpreter, "log timers", + "Enable, disable, dump, and reset LLDB internal " + "performance timers.", + "log timers < enable <depth> | disable | dump | " + "increment <bool> | reset >") { + LoadSubCommand("enable", CommandObjectSP( + new CommandObjectLogTimerEnable(interpreter))); + LoadSubCommand("disable", CommandObjectSP(new CommandObjectLogTimerDisable( + interpreter))); + LoadSubCommand("dump", + CommandObjectSP(new CommandObjectLogTimerDump(interpreter))); + LoadSubCommand( + "reset", CommandObjectSP(new CommandObjectLogTimerReset(interpreter))); + LoadSubCommand( + "increment", + CommandObjectSP(new CommandObjectLogTimerIncrement(interpreter))); + } + + ~CommandObjectLogTimer() override = default; +}; + CommandObjectLog::CommandObjectLog(CommandInterpreter &interpreter) : CommandObjectMultiword(interpreter, "log", "Commands controlling LLDB internal logging.", diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectLog.h b/contrib/llvm-project/lldb/source/Commands/CommandObjectLog.h index eae41bf6b8d1..8dc3f1b7b9e9 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectLog.h +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectLog.h @@ -6,9 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CommandObjectLog_h_ -#define liblldb_CommandObjectLog_h_ - +#ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTLOG_H +#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTLOG_H #include "lldb/Interpreter/CommandObjectMultiword.h" @@ -25,9 +24,10 @@ public: private: // For CommandObjectLog only - DISALLOW_COPY_AND_ASSIGN(CommandObjectLog); + CommandObjectLog(const CommandObjectLog &) = delete; + const CommandObjectLog &operator=(const CommandObjectLog &) = delete; }; } // namespace lldb_private -#endif // liblldb_CommandObjectLog_h_ +#endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTLOG_H diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectMemory.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectMemory.cpp index e497b5246b8d..474c37710149 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectMemory.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectMemory.cpp @@ -1,4 +1,4 @@ -//===-- CommandObjectMemory.cpp ---------------------------------*- C++ -*-===// +//===-- CommandObjectMemory.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectMemory.h b/contrib/llvm-project/lldb/source/Commands/CommandObjectMemory.h index f94cdf3287aa..5f7f6bb30b88 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectMemory.h +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectMemory.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CommandObjectMemory_h_ -#define liblldb_CommandObjectMemory_h_ +#ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTMEMORY_H +#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTMEMORY_H #include "lldb/Interpreter/CommandObjectMultiword.h" @@ -22,4 +22,4 @@ public: } // namespace lldb_private -#endif // liblldb_CommandObjectMemory_h_ +#endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTMEMORY_H diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectMultiword.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectMultiword.cpp index 67225d3d6b8d..9033cfebf46b 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectMultiword.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectMultiword.cpp @@ -1,4 +1,4 @@ -//===-- CommandObjectMultiword.cpp ------------------------------*- C++ -*-===// +//===-- CommandObjectMultiword.cpp ----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -32,7 +32,7 @@ CommandObjectSP CommandObjectMultiword::GetSubcommandSP(llvm::StringRef sub_cmd, CommandObject::CommandMap::iterator pos; if (!m_subcommand_dict.empty()) { - pos = m_subcommand_dict.find(sub_cmd); + pos = m_subcommand_dict.find(std::string(sub_cmd)); if (pos != m_subcommand_dict.end()) { // An exact match; append the sub_cmd to the 'matches' string list. if (matches) @@ -50,7 +50,7 @@ CommandObjectSP CommandObjectMultiword::GetSubcommandSP(llvm::StringRef sub_cmd, // function, since I now know I have an exact match... sub_cmd = matches->GetStringAtIndex(0); - pos = m_subcommand_dict.find(sub_cmd); + pos = m_subcommand_dict.find(std::string(sub_cmd)); if (pos != m_subcommand_dict.end()) return_cmd_sp = pos->second; } @@ -74,9 +74,9 @@ bool CommandObjectMultiword::LoadSubCommand(llvm::StringRef name, CommandMap::iterator pos; bool success = true; - pos = m_subcommand_dict.find(name); + pos = m_subcommand_dict.find(std::string(name)); if (pos == m_subcommand_dict.end()) { - m_subcommand_dict[name] = cmd_obj; + m_subcommand_dict[std::string(name)] = cmd_obj; } else success = false; @@ -130,9 +130,9 @@ bool CommandObjectMultiword::Execute(const char *args_string, error_msg.assign("invalid command "); error_msg.append("'"); - error_msg.append(GetCommandName()); + error_msg.append(std::string(GetCommandName())); error_msg.append(" "); - error_msg.append(sub_command); + error_msg.append(std::string(sub_command)); error_msg.append("'."); if (num_subcmd_matches > 0) { @@ -165,15 +165,14 @@ void CommandObjectMultiword::GenerateHelpText(Stream &output_stream) { std::string indented_command(" "); indented_command.append(pos->first); if (pos->second->WantsRawCommandString()) { - std::string help_text(pos->second->GetHelp()); + std::string help_text(std::string(pos->second->GetHelp())); help_text.append(" Expects 'raw' input (see 'help raw-input'.)"); - m_interpreter.OutputFormattedHelpText(output_stream, - indented_command.c_str(), "--", - help_text.c_str(), max_len); + m_interpreter.OutputFormattedHelpText(output_stream, indented_command, + "--", help_text, max_len); } else - m_interpreter.OutputFormattedHelpText(output_stream, - indented_command.c_str(), "--", - pos->second->GetHelp(), max_len); + m_interpreter.OutputFormattedHelpText(output_stream, indented_command, + "--", pos->second->GetHelp(), + max_len); } output_stream.PutCString("\nFor more help on any particular subcommand, type " diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectPlatform.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectPlatform.cpp index 10e6a4aa1793..fcc8af6f915c 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectPlatform.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectPlatform.cpp @@ -1,4 +1,4 @@ -//===-- CommandObjectPlatform.cpp -------------------------------*- C++ -*-===// +//===-- CommandObjectPlatform.cpp -----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -11,7 +11,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/CommandOptionValidators.h" #include "lldb/Interpreter/CommandReturnObject.h" @@ -133,7 +132,8 @@ public: uint32_t m_permissions; private: - DISALLOW_COPY_AND_ASSIGN(OptionPermissions); + OptionPermissions(const OptionPermissions &) = delete; + const OptionPermissions &operator=(const OptionPermissions &) = delete; }; // "platform select <platform-name>" @@ -421,7 +421,6 @@ protected: return &m_options; } -protected: OptionGroupOptions m_options; OptionGroupFile m_option_working_dir; }; @@ -546,8 +545,13 @@ public: if (platform_sp) { std::string cmd_line; args.GetCommandString(cmd_line); - const lldb::user_id_t fd = - StringConvert::ToUInt64(cmd_line.c_str(), UINT64_MAX); + lldb::user_id_t fd; + if (!llvm::to_integer(cmd_line, fd)) { + result.AppendErrorWithFormatv("'{0}' is not a valid file descriptor.\n", + cmd_line); + result.SetStatus(eReturnStatusFailed); + return result.Succeeded(); + } Status error; bool success = platform_sp->CloseFile(fd, error); if (success) { @@ -586,8 +590,13 @@ public: if (platform_sp) { std::string cmd_line; args.GetCommandString(cmd_line); - const lldb::user_id_t fd = - StringConvert::ToUInt64(cmd_line.c_str(), UINT64_MAX); + lldb::user_id_t fd; + if (!llvm::to_integer(cmd_line, fd)) { + result.AppendErrorWithFormatv("'{0}' is not a valid file descriptor.\n", + cmd_line); + result.SetStatus(eReturnStatusFailed); + return result.Succeeded(); + } std::string buffer(m_options.m_count, 0); Status error; uint32_t retcode = platform_sp->ReadFile( @@ -674,8 +683,13 @@ public: std::string cmd_line; args.GetCommandString(cmd_line); Status error; - const lldb::user_id_t fd = - StringConvert::ToUInt64(cmd_line.c_str(), UINT64_MAX); + lldb::user_id_t fd; + if (!llvm::to_integer(cmd_line, fd)) { + result.AppendErrorWithFormatv("'{0}' is not a valid file descriptor.", + cmd_line); + result.SetStatus(eReturnStatusFailed); + return result.Succeeded(); + } uint32_t retcode = platform_sp->WriteFile(fd, m_options.m_offset, &m_options.m_data[0], m_options.m_data.size(), error); @@ -709,7 +723,7 @@ protected: option_arg.str().c_str()); break; case 'd': - m_data.assign(option_arg); + m_data.assign(std::string(option_arg)); break; default: llvm_unreachable("Unimplemented option"); @@ -758,7 +772,9 @@ public: private: // For CommandObjectPlatform only - DISALLOW_COPY_AND_ASSIGN(CommandObjectPlatformFile); + CommandObjectPlatformFile(const CommandObjectPlatformFile &) = delete; + const CommandObjectPlatformFile & + operator=(const CommandObjectPlatformFile &) = delete; }; // "platform get-file remote-file-path host-file-path" @@ -1020,7 +1036,6 @@ protected: return result.Succeeded(); } -protected: ProcessLaunchCommandOptions m_options; }; @@ -1128,7 +1143,7 @@ protected: ProcessInstanceInfo::DumpTableHeader(ostrm, m_options.show_args, m_options.verbose); for (uint32_t i = 0; i < matches; ++i) { - proc_infos.GetProcessInfoAtIndex(i).DumpAsTableRow( + proc_infos[i].DumpAsTableRow( ostrm, platform_sp->GetUserIDResolver(), m_options.show_args, m_options.verbose); } @@ -1462,12 +1477,12 @@ public: match_info.SetNameMatchType(NameMatch::StartsWith); } platform_sp->FindProcesses(match_info, process_infos); - const uint32_t num_matches = process_infos.GetSize(); + const uint32_t num_matches = process_infos.size(); if (num_matches == 0) return; for (uint32_t i = 0; i < num_matches; ++i) { - request.AddCompletion(process_infos.GetProcessNameAtIndex(i)); + request.AddCompletion(process_infos[i].GetNameAsStringRef()); } return; } @@ -1541,7 +1556,9 @@ public: private: // For CommandObjectPlatform only - DISALLOW_COPY_AND_ASSIGN(CommandObjectPlatformProcess); + CommandObjectPlatformProcess(const CommandObjectPlatformProcess &) = delete; + const CommandObjectPlatformProcess & + operator=(const CommandObjectPlatformProcess &) = delete; }; // "platform shell" @@ -1567,6 +1584,9 @@ public: const char short_option = (char)GetDefinitions()[option_idx].short_option; switch (short_option) { + case 'h': + m_use_host_platform = true; + break; case 't': uint32_t timeout_sec; if (option_arg.getAsInteger(10, timeout_sec)) @@ -1574,7 +1594,7 @@ public: "could not convert \"%s\" to a numeric value.", option_arg.str().c_str()); else - timeout = std::chrono::seconds(timeout_sec); + m_timeout = std::chrono::seconds(timeout_sec); break; default: llvm_unreachable("Unimplemented option"); @@ -1583,9 +1603,13 @@ public: return error; } - void OptionParsingStarting(ExecutionContext *execution_context) override {} + void OptionParsingStarting(ExecutionContext *execution_context) override { + m_timeout.reset(); + m_use_host_platform = false; + } - Timeout<std::micro> timeout = std::chrono::seconds(10); + Timeout<std::micro> m_timeout = std::chrono::seconds(10); + bool m_use_host_platform; }; CommandObjectPlatformShell(CommandInterpreter &interpreter) @@ -1609,6 +1633,7 @@ public: return true; } + const bool is_alias = !raw_command_line.contains("platform"); OptionsWithRaw args(raw_command_line); const char *expr = args.GetRawPart().c_str(); @@ -1616,8 +1641,16 @@ public: if (!ParseOptions(args.GetArgs(), result)) return false; + if (args.GetRawPart().empty()) { + result.GetOutputStream().Printf("%s <shell-command>\n", + is_alias ? "shell" : "platform shell"); + return false; + } + PlatformSP platform_sp( - GetDebugger().GetPlatformList().GetSelectedPlatform()); + m_options.m_use_host_platform + ? Platform::GetHostPlatform() + : GetDebugger().GetPlatformList().GetSelectedPlatform()); Status error; if (platform_sp) { FileSpec working_dir{}; @@ -1625,7 +1658,7 @@ public: int status = -1; int signo = -1; error = (platform_sp->RunShellCommand(expr, working_dir, &status, &signo, - &output, m_options.timeout)); + &output, m_options.m_timeout)); if (!output.empty()) result.GetOutputStream().PutCString(output); if (status > 0) { diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectPlatform.h b/contrib/llvm-project/lldb/source/Commands/CommandObjectPlatform.h index 45e4a41c5b20..86f55c7d9b08 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectPlatform.h +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectPlatform.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CommandObjectPlatform_h_ -#define liblldb_CommandObjectPlatform_h_ +#ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTPLATFORM_H +#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTPLATFORM_H #include "lldb/Interpreter/CommandObjectMultiword.h" @@ -22,9 +22,11 @@ public: ~CommandObjectPlatform() override; private: - DISALLOW_COPY_AND_ASSIGN(CommandObjectPlatform); + CommandObjectPlatform(const CommandObjectPlatform &) = delete; + const CommandObjectPlatform & + operator=(const CommandObjectPlatform &) = delete; }; } // namespace lldb_private -#endif // liblldb_CommandObjectPlatform_h_ +#endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTPLATFORM_H diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectPlugin.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectPlugin.cpp index 6fcb64f207b2..98a212eef0fa 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectPlugin.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectPlugin.cpp @@ -1,4 +1,4 @@ -//===-- CommandObjectPlugin.cpp ---------------------------------*- C++ -*-===// +//===-- CommandObjectPlugin.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectPlugin.h b/contrib/llvm-project/lldb/source/Commands/CommandObjectPlugin.h index 94cea7db4111..6db9f0a40a40 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectPlugin.h +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectPlugin.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CommandObjectPlugin_h_ -#define liblldb_CommandObjectPlugin_h_ +#ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTPLUGIN_H +#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTPLUGIN_H #include "lldb/Interpreter/CommandObjectMultiword.h" @@ -22,4 +22,4 @@ public: } // namespace lldb_private -#endif // liblldb_CommandObjectPlugin_h_ +#endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTPLUGIN_H diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectProcess.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectProcess.cpp index d825647728f8..f86779d85b5f 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectProcess.cpp +++ b/contrib/llvm-project/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; } diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectProcess.h b/contrib/llvm-project/lldb/source/Commands/CommandObjectProcess.h index 3b1ff26dbb05..55d445142e72 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectProcess.h +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectProcess.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CommandObjectProcess_h_ -#define liblldb_CommandObjectProcess_h_ +#ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTPROCESS_H +#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTPROCESS_H #include "lldb/Interpreter/CommandObjectMultiword.h" @@ -24,4 +24,4 @@ public: } // namespace lldb_private -#endif // liblldb_CommandObjectProcess_h_ +#endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTPROCESS_H diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectQuit.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectQuit.cpp index 70ee336f8a1b..d0c7bbd3abf8 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectQuit.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectQuit.cpp @@ -1,4 +1,4 @@ -//===-- CommandObjectQuit.cpp -----------------------------------*- C++ -*-===// +//===-- CommandObjectQuit.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectQuit.h b/contrib/llvm-project/lldb/source/Commands/CommandObjectQuit.h index 458ef2456fca..ccbd863cd6f5 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectQuit.h +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectQuit.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CommandObjectQuit_h_ -#define liblldb_CommandObjectQuit_h_ +#ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTQUIT_H +#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTQUIT_H #include "lldb/Interpreter/CommandObject.h" @@ -29,4 +29,4 @@ protected: } // namespace lldb_private -#endif // liblldb_CommandObjectQuit_h_ +#endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTQUIT_H diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectRegister.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectRegister.cpp index 523b32a996b2..56e8c3fb4b84 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectRegister.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectRegister.cpp @@ -1,4 +1,4 @@ -//===-- CommandObjectRegister.cpp -------------------------------*- C++ -*-===// +//===-- CommandObjectRegister.cpp -----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -70,6 +70,17 @@ public: ~CommandObjectRegisterRead() override = default; + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { + if (!m_exe_ctx.HasProcessScope()) + return; + + CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), CommandCompletions::eRegisterCompletion, + request, nullptr); + } + Options *GetOptions() override { return &m_option_group; } bool DumpRegister(const ExecutionContext &exe_ctx, Stream &strm, @@ -323,6 +334,17 @@ public: ~CommandObjectRegisterWrite() override = default; + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { + if (!m_exe_ctx.HasProcessScope() || request.GetCursorIndex() != 0) + return; + + CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), CommandCompletions::eRegisterCompletion, + request, nullptr); + } + protected: bool DoExecute(Args &command, CommandReturnObject &result) override { DataExtractor reg_data; diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectRegister.h b/contrib/llvm-project/lldb/source/Commands/CommandObjectRegister.h index 6fc47cf386a3..671ffc570147 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectRegister.h +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectRegister.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CommandObjectRegister_h_ -#define liblldb_CommandObjectRegister_h_ +#ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTREGISTER_H +#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTREGISTER_H #include "lldb/Interpreter/CommandObjectMultiword.h" @@ -24,9 +24,11 @@ public: private: // For CommandObjectRegister only - DISALLOW_COPY_AND_ASSIGN(CommandObjectRegister); + CommandObjectRegister(const CommandObjectRegister &) = delete; + const CommandObjectRegister & + operator=(const CommandObjectRegister &) = delete; }; } // namespace lldb_private -#endif // liblldb_CommandObjectRegister_h_ +#endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTREGISTER_H diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectReproducer.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectReproducer.cpp index d15f622314d9..104130b70b2b 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectReproducer.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectReproducer.cpp @@ -1,4 +1,4 @@ -//===-- CommandObjectReproducer.cpp -----------------------------*- C++ -*-===// +//===-- CommandObjectReproducer.cpp ---------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -8,13 +8,14 @@ #include "CommandObjectReproducer.h" +#include "lldb/Host/HostInfo.h" #include "lldb/Host/OptionParser.h" -#include "lldb/Utility/GDBRemote.h" -#include "lldb/Utility/Reproducer.h" - #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" #include "lldb/Interpreter/OptionArgParser.h" +#include "lldb/Utility/GDBRemote.h" +#include "lldb/Utility/ProcessInfo.h" +#include "lldb/Utility/Reproducer.h" #include <csignal> @@ -27,6 +28,7 @@ enum ReproducerProvider { eReproducerProviderCommands, eReproducerProviderFiles, eReproducerProviderGDB, + eReproducerProviderProcessInfo, eReproducerProviderVersion, eReproducerProviderWorkingDirectory, eReproducerProviderNone @@ -49,6 +51,11 @@ static constexpr OptionEnumValueElement g_reproducer_provider_type[] = { "GDB Remote Packets", }, { + eReproducerProviderProcessInfo, + "processes", + "Process Info", + }, + { eReproducerProviderVersion, "version", "Version", @@ -97,6 +104,24 @@ static constexpr OptionEnumValues ReproducerSignalType() { #define LLDB_OPTIONS_reproducer_xcrash #include "CommandOptions.inc" +template <typename T> +llvm::Expected<T> static ReadFromYAML(StringRef filename) { + auto error_or_file = MemoryBuffer::getFile(filename); + if (auto err = error_or_file.getError()) { + return errorCodeToError(err); + } + + T t; + yaml::Input yin((*error_or_file)->getBuffer()); + yin >> t; + + if (auto err = yin.error()) { + return errorCodeToError(err); + } + + return t; +} + class CommandObjectReproducerGenerate : public CommandObjectParsed { public: CommandObjectReproducerGenerate(CommandInterpreter &interpreter) @@ -258,6 +283,18 @@ protected: result.GetOutputStream() << "Reproducer is off.\n"; } + if (r.IsCapturing() || r.IsReplaying()) { + result.GetOutputStream() + << "Path: " << r.GetReproducerPath().GetPath() << '\n'; + } + + // Auto generate is hidden unless enabled because this is mostly for + // development and testing. + if (Generator *g = r.GetGenerator()) { + if (g->IsAutoGenerate()) + result.GetOutputStream() << "Auto generate: on\n"; + } + result.SetStatus(eReturnStatusSuccessFinishResult); return result.Succeeded(); } @@ -410,8 +447,8 @@ protected: repro::MultiLoader<repro::CommandProvider>::Create(loader); if (!multi_loader) { SetError(result, - make_error<StringError>(llvm::inconvertibleErrorCode(), - "Unable to create command loader.")); + make_error<StringError>("Unable to create command loader.", + llvm::inconvertibleErrorCode())); return false; } @@ -436,26 +473,52 @@ protected: std::unique_ptr<repro::MultiLoader<repro::GDBRemoteProvider>> multi_loader = repro::MultiLoader<repro::GDBRemoteProvider>::Create(loader); + + if (!multi_loader) { + SetError(result, + make_error<StringError>("Unable to create GDB loader.", + llvm::inconvertibleErrorCode())); + return false; + } + llvm::Optional<std::string> gdb_file; while ((gdb_file = multi_loader->GetNextFile())) { - auto error_or_file = MemoryBuffer::getFile(*gdb_file); - if (auto err = error_or_file.getError()) { - SetError(result, errorCodeToError(err)); + if (llvm::Expected<std::vector<GDBRemotePacket>> packets = + ReadFromYAML<std::vector<GDBRemotePacket>>(*gdb_file)) { + for (GDBRemotePacket &packet : *packets) { + packet.Dump(result.GetOutputStream()); + } + } else { + SetError(result, packets.takeError()); return false; } + } + + result.SetStatus(eReturnStatusSuccessFinishResult); + return true; + } + case eReproducerProviderProcessInfo: { + std::unique_ptr<repro::MultiLoader<repro::ProcessInfoProvider>> + multi_loader = + repro::MultiLoader<repro::ProcessInfoProvider>::Create(loader); - std::vector<GDBRemotePacket> packets; - yaml::Input yin((*error_or_file)->getBuffer()); - yin >> packets; + if (!multi_loader) { + SetError(result, make_error<StringError>( + llvm::inconvertibleErrorCode(), + "Unable to create process info loader.")); + return false; + } - if (auto err = yin.error()) { - SetError(result, errorCodeToError(err)); + llvm::Optional<std::string> process_file; + while ((process_file = multi_loader->GetNextFile())) { + if (llvm::Expected<ProcessInstanceInfoList> infos = + ReadFromYAML<ProcessInstanceInfoList>(*process_file)) { + for (ProcessInstanceInfo info : *infos) + info.Dump(result.GetOutputStream(), HostInfo::GetUserIDResolver()); + } else { + SetError(result, infos.takeError()); return false; } - - for (GDBRemotePacket &packet : packets) { - packet.Dump(result.GetOutputStream()); - } } result.SetStatus(eReturnStatusSuccessFinishResult); diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectReproducer.h b/contrib/llvm-project/lldb/source/Commands/CommandObjectReproducer.h index 8a85c21d6510..bdee8053549f 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectReproducer.h +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectReproducer.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CommandObjectReproducer_h_ -#define liblldb_CommandObjectReproducer_h_ +#ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTREPRODUCER_H +#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTREPRODUCER_H #include "lldb/Interpreter/CommandObjectMultiword.h" @@ -24,4 +24,4 @@ public: } // namespace lldb_private -#endif // liblldb_CommandObjectReproducer_h_ +#endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTREPRODUCER_H diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectSettings.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectSettings.cpp index 95f79f45e22b..87e0352636e1 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectSettings.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectSettings.cpp @@ -1,4 +1,4 @@ -//===-- CommandObjectSettings.cpp -------------------------------*- C++ -*-===// +//===-- CommandObjectSettings.cpp -----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -343,7 +343,7 @@ public: switch (short_option) { case 'f': - m_filename.assign(option_arg); + m_filename.assign(std::string(option_arg)); break; case 'a': m_append = true; @@ -444,7 +444,7 @@ public: switch (short_option) { case 'f': - m_filename.assign(option_arg); + m_filename.assign(std::string(option_arg)); break; default: llvm_unreachable("Unimplemented option"); @@ -531,10 +531,8 @@ protected: if (argc > 0) { const bool dump_qualified_name = true; - // TODO: Convert to StringRef based enumeration. Requires converting - // GetPropertyAtPath first. - for (size_t i = 0; i < argc; ++i) { - const char *property_path = args.GetArgumentAtIndex(i); + for (const Args::ArgEntry &arg : args) { + const char *property_path = arg.c_str(); const Property *property = GetDebugger().GetValueProperties()->GetPropertyAtPath( @@ -1043,13 +1041,16 @@ protected: }; // CommandObjectSettingsClear +#define LLDB_OPTIONS_settings_clear +#include "CommandOptions.inc" class CommandObjectSettingsClear : public CommandObjectParsed { public: CommandObjectSettingsClear(CommandInterpreter &interpreter) : CommandObjectParsed( interpreter, "settings clear", - "Clear a debugger setting array, dictionary, or string.", nullptr) { + "Clear a debugger setting array, dictionary, or string. " + "If '-a' option is specified, it clears all settings.", nullptr) { CommandArgumentEntry arg; CommandArgumentData var_name_arg; @@ -1077,11 +1078,53 @@ public: request, nullptr); } + 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 { + const int short_option = m_getopt_table[option_idx].val; + switch (short_option) { + case 'a': + m_clear_all = true; + break; + default: + llvm_unreachable("Unimplemented option"); + } + return Status(); + } + + void OptionParsingStarting(ExecutionContext *execution_context) override { + m_clear_all = false; + } + + llvm::ArrayRef<OptionDefinition> GetDefinitions() override { + return llvm::makeArrayRef(g_settings_clear_options); + } + + bool m_clear_all = false; + }; + protected: bool DoExecute(Args &command, CommandReturnObject &result) override { result.SetStatus(eReturnStatusSuccessFinishNoResult); const size_t argc = command.GetArgumentCount(); + if (m_options.m_clear_all) { + if (argc != 0) { + result.AppendError("'settings clear --all' doesn't take any arguments"); + result.SetStatus(eReturnStatusFailed); + return false; + } + GetDebugger().GetValueProperties()->Clear(); + return result.Succeeded(); + } + if (argc != 1) { result.AppendError("'settings clear' takes exactly one argument"); result.SetStatus(eReturnStatusFailed); @@ -1106,6 +1149,9 @@ protected: return result.Succeeded(); } + + private: + CommandOptions m_options; }; // CommandObjectMultiwordSettings diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectSettings.h b/contrib/llvm-project/lldb/source/Commands/CommandObjectSettings.h index 4db0ca1f83f8..31ec1d3bef16 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectSettings.h +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectSettings.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CommandObjectSettings_h_ -#define liblldb_CommandObjectSettings_h_ +#ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTSETTINGS_H +#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTSETTINGS_H #include "lldb/Interpreter/CommandObjectMultiword.h" @@ -24,4 +24,4 @@ public: } // namespace lldb_private -#endif // liblldb_CommandObjectSettings_h_ +#endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTSETTINGS_H diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectSource.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectSource.cpp index 19a554fb290a..1ccfd3a5166f 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectSource.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectSource.cpp @@ -1,4 +1,4 @@ -//===-- CommandObjectSource.cpp ---------------------------------*- C++ -*-===// +//===-- CommandObjectSource.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -63,11 +63,11 @@ class CommandObjectSourceInfo : public CommandObjectParsed { break; case 'f': - file_name = option_arg; + file_name = std::string(option_arg); break; case 'n': - symbol_name = option_arg; + symbol_name = std::string(option_arg); break; case 'a': { @@ -646,11 +646,11 @@ class CommandObjectSourceList : public CommandObjectParsed { break; case 'f': - file_name = option_arg; + file_name = std::string(option_arg); break; case 'n': - symbol_name = option_arg; + symbol_name = std::string(option_arg); break; case 'a': { diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectSource.h b/contrib/llvm-project/lldb/source/Commands/CommandObjectSource.h index a4b8823a4fa9..f2117bd6ca3f 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectSource.h +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectSource.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CommandObjectSource_h_ -#define liblldb_CommandObjectSource_h_ +#ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTSOURCE_H +#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTSOURCE_H #include "lldb/Interpreter/CommandObjectMultiword.h" @@ -25,4 +25,4 @@ public: } // namespace lldb_private -#endif // liblldb_CommandObjectSource_h_ +#endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTSOURCE_H diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectStats.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectStats.cpp index eeec4a8d3e77..6b06581f5a8f 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectStats.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectStats.cpp @@ -1,4 +1,4 @@ -//===-- CommandObjectStats.cpp ----------------------------------*- C++ -*-===// +//===-- CommandObjectStats.cpp --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectStats.h b/contrib/llvm-project/lldb/source/Commands/CommandObjectStats.h index 593c4521e175..c4cd6340f67b 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectStats.h +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectStats.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CommandObjectStats_h_ -#define liblldb_CommandObjectStats_h_ +#ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTSTATS_H +#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTSTATS_H #include "lldb/Interpreter/CommandObjectMultiword.h" @@ -20,4 +20,4 @@ public: }; } // namespace lldb_private -#endif // liblldb_CommandObjectLanguage_h_ +#endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTSTATS_H diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectTarget.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectTarget.cpp index 8738e850c9f7..7bb71f4d518c 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectTarget.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectTarget.cpp @@ -1,4 +1,4 @@ -//===-- CommandObjectTarget.cpp ---------------------------------*- C++ -*-===// +//===-- CommandObjectTarget.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -16,7 +16,6 @@ #include "lldb/Core/ValueObjectVariable.h" #include "lldb/DataFormatters/ValueObjectPrinter.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" @@ -200,7 +199,9 @@ public: LoadDependentFiles m_load_dependent_files; private: - DISALLOW_COPY_AND_ASSIGN(OptionGroupDependents); + OptionGroupDependents(const OptionGroupDependents &) = delete; + const OptionGroupDependents & + operator=(const OptionGroupDependents &) = delete; }; #pragma mark CommandObjectTargetCreate @@ -271,15 +272,13 @@ protected: FileSpec remote_file(m_remote_file.GetOptionValue().GetCurrentValue()); if (core_file) { - if (!FileSystem::Instance().Exists(core_file)) { - result.AppendErrorWithFormat("core file '%s' doesn't exist", - core_file.GetPath().c_str()); - result.SetStatus(eReturnStatusFailed); - return false; - } - if (!FileSystem::Instance().Readable(core_file)) { - result.AppendErrorWithFormat("core file '%s' is not readable", - core_file.GetPath().c_str()); + auto file = FileSystem::Instance().Open( + core_file, lldb_private::File::eOpenOptionRead); + + if (!file) { + result.AppendErrorWithFormatv("Cannot open '{0}': {1}.", + core_file.GetPath(), + llvm::toString(file.takeError())); result.SetStatus(eReturnStatusFailed); return false; } @@ -288,18 +287,13 @@ protected: if (argc == 1 || core_file || remote_file) { FileSpec symfile(m_symbol_file.GetOptionValue().GetCurrentValue()); if (symfile) { - if (FileSystem::Instance().Exists(symfile)) { - if (!FileSystem::Instance().Readable(symfile)) { - result.AppendErrorWithFormat("symbol file '%s' is not readable", - symfile.GetPath().c_str()); - result.SetStatus(eReturnStatusFailed); - return false; - } - } else { - char symfile_path[PATH_MAX]; - symfile.GetPath(symfile_path, sizeof(symfile_path)); - result.AppendErrorWithFormat("invalid symbol file path '%s'", - symfile_path); + auto file = FileSystem::Instance().Open( + symfile, lldb_private::File::eOpenOptionRead); + + if (!file) { + result.AppendErrorWithFormatv("Cannot open '{0}': {1}.", + symfile.GetPath(), + llvm::toString(file.takeError())); result.SetStatus(eReturnStatusFailed); return false; } @@ -401,48 +395,34 @@ protected: if (module_sp) module_sp->SetPlatformFileSpec(remote_file); } + if (core_file) { - char core_path[PATH_MAX]; - core_file.GetPath(core_path, sizeof(core_path)); - if (FileSystem::Instance().Exists(core_file)) { - if (!FileSystem::Instance().Readable(core_file)) { - result.AppendMessageWithFormat( - "Core file '%s' is not readable.\n", core_path); - result.SetStatus(eReturnStatusFailed); - return false; - } - FileSpec core_file_dir; - core_file_dir.GetDirectory() = core_file.GetDirectory(); - target_sp->AppendExecutableSearchPaths(core_file_dir); + FileSpec core_file_dir; + core_file_dir.GetDirectory() = core_file.GetDirectory(); + target_sp->AppendExecutableSearchPaths(core_file_dir); - ProcessSP process_sp(target_sp->CreateProcess( - GetDebugger().GetListener(), llvm::StringRef(), &core_file)); + ProcessSP process_sp(target_sp->CreateProcess( + GetDebugger().GetListener(), llvm::StringRef(), &core_file)); - if (process_sp) { - // Seems weird that we Launch a core file, but that is what we - // do! - error = process_sp->LoadCore(); + if (process_sp) { + // Seems weird that we Launch a core file, but that is what we + // do! + error = process_sp->LoadCore(); - if (error.Fail()) { - result.AppendError( - error.AsCString("can't find plug-in for core file")); - result.SetStatus(eReturnStatusFailed); - return false; - } else { - result.AppendMessageWithFormat( - "Core file '%s' (%s) was loaded.\n", core_path, - target_sp->GetArchitecture().GetArchitectureName()); - result.SetStatus(eReturnStatusSuccessFinishNoResult); - } - } else { - result.AppendErrorWithFormat( - "Unable to find process plug-in for core file '%s'\n", - core_path); + if (error.Fail()) { + result.AppendError( + error.AsCString("can't find plug-in for core file")); result.SetStatus(eReturnStatusFailed); + return false; + } else { + result.AppendMessageWithFormatv("Core file '{0}' ({1}) was loaded.\n", core_file.GetPath(), + target_sp->GetArchitecture().GetArchitectureName()); + result.SetStatus(eReturnStatusSuccessFinishNoResult); } } else { - result.AppendErrorWithFormat("Core file '%s' does not exist\n", - core_path); + result.AppendErrorWithFormatv( + "Unable to find process plug-in for core file '{0}'\n", + core_file.GetPath()); result.SetStatus(eReturnStatusFailed); } } else { @@ -525,11 +505,9 @@ public: protected: bool DoExecute(Args &args, CommandReturnObject &result) override { if (args.GetArgumentCount() == 1) { - bool success = false; const char *target_idx_arg = args.GetArgumentAtIndex(0); - uint32_t target_idx = - StringConvert::ToUInt32(target_idx_arg, UINT32_MAX, 0, &success); - if (success) { + uint32_t target_idx; + if (llvm::to_integer(target_idx_arg, target_idx)) { TargetList &target_list = GetDebugger().GetTargetList(); const uint32_t num_targets = target_list.GetNumTargets(); if (target_idx < num_targets) { @@ -571,7 +549,7 @@ protected: } }; -#pragma mark CommandObjectTargetSelect +#pragma mark CommandObjectTargetDelete // "target delete" @@ -682,6 +660,41 @@ protected: OptionGroupBoolean m_cleanup_option; }; +class CommandObjectTargetShowLaunchEnvironment : public CommandObjectParsed { +public: + CommandObjectTargetShowLaunchEnvironment(CommandInterpreter &interpreter) + : CommandObjectParsed( + interpreter, "target show-launch-environment", + "Shows the environment being passed to the process when launched, " + "taking info account 3 settings: target.env-vars, " + "target.inherit-env and target.unset-env-vars.", + nullptr, eCommandRequiresTarget) {} + + ~CommandObjectTargetShowLaunchEnvironment() override = default; + +protected: + bool DoExecute(Args &args, CommandReturnObject &result) override { + Target *target = m_exe_ctx.GetTargetPtr(); + Environment env = target->GetEnvironment(); + + std::vector<Environment::value_type *> env_vector; + env_vector.reserve(env.size()); + for (auto &KV : env) + env_vector.push_back(&KV); + std::sort(env_vector.begin(), env_vector.end(), + [](Environment::value_type *a, Environment::value_type *b) { + return a->first() < b->first(); + }); + + auto &strm = result.GetOutputStream(); + for (auto &KV : env_vector) + strm.Format("{0}={1}\n", KV->first(), KV->second); + + result.SetStatus(eReturnStatusSuccessFinishResult); + return result.Succeeded(); + } +}; + #pragma mark CommandObjectTargetVariable // "target variable" @@ -841,21 +854,18 @@ protected: Stream &s = result.GetOutputStream(); if (argc > 0) { - - // TODO: Convert to entry-based iteration. Requires converting - // DumpValueObject. - for (size_t idx = 0; idx < argc; ++idx) { + for (const Args::ArgEntry &arg : args) { VariableList variable_list; ValueObjectList valobj_list; - const char *arg = args.GetArgumentAtIndex(idx); size_t matches = 0; bool use_var_name = false; if (m_option_variable.use_regex) { - RegularExpression regex(llvm::StringRef::withNullAsEmpty(arg)); + RegularExpression regex( + llvm::StringRef::withNullAsEmpty(arg.c_str())); if (!regex.IsValid()) { result.GetErrorStream().Printf( - "error: invalid regular expression: '%s'\n", arg); + "error: invalid regular expression: '%s'\n", arg.c_str()); result.SetStatus(eReturnStatusFailed); return false; } @@ -865,14 +875,14 @@ protected: matches = variable_list.GetSize(); } else { Status error(Variable::GetValuesForVariableExpressionPath( - arg, m_exe_ctx.GetBestExecutionContextScope(), + arg.c_str(), m_exe_ctx.GetBestExecutionContextScope(), GetVariableCallback, target, variable_list, valobj_list)); matches = variable_list.GetSize(); } if (matches == 0) { result.GetErrorStream().Printf( - "error: can't find global variable '%s'\n", arg); + "error: can't find global variable '%s'\n", arg.c_str()); result.SetStatus(eReturnStatusFailed); return false; } else { @@ -888,7 +898,7 @@ protected: if (valobj_sp) DumpValueObject(s, var_sp, valobj_sp, use_var_name ? var_sp->GetName().GetCString() - : arg); + : arg.c_str()); } } } @@ -1163,12 +1173,9 @@ protected: size_t argc = command.GetArgumentCount(); // check for at least 3 arguments and an odd number of parameters if (argc >= 3 && argc & 1) { - bool success = false; - - uint32_t insert_idx = StringConvert::ToUInt32( - command.GetArgumentAtIndex(0), UINT32_MAX, 0, &success); + uint32_t insert_idx; - if (!success) { + if (!llvm::to_integer(command.GetArgumentAtIndex(0), insert_idx)) { result.AppendErrorWithFormat( "<index> parameter is not an integer: '%s'.\n", command.GetArgumentAtIndex(0)); @@ -1292,7 +1299,7 @@ static void DumpModuleArchitecture(Stream &strm, Module *module, module->GetArchitecture().DumpTriple(arch_strm.AsRawOstream()); else arch_strm.PutCString(module->GetArchitecture().GetArchitectureName()); - std::string arch_str = arch_strm.GetString(); + std::string arch_str = std::string(arch_strm.GetString()); if (width) strm.Printf("%-*s", width, arch_str.c_str()); @@ -1431,11 +1438,9 @@ static void DumpModuleSections(CommandInterpreter &interpreter, Stream &strm, strm.Printf("Sections for '%s' (%s):\n", module->GetSpecificationDescription().c_str(), module->GetArchitecture().GetArchitectureName()); - strm.IndentMore(); - section_list->Dump(&strm, + section_list->Dump(strm.AsRawOstream(), strm.GetIndentLevel() + 2, interpreter.GetExecutionContext().GetTargetPtr(), true, UINT32_MAX); - strm.IndentLess(); } } } @@ -1599,8 +1604,9 @@ static size_t LookupFunctionInModule(CommandInterpreter &interpreter, include_inlines, sc_list); } else { ConstString function_name(name); - module->FindFunctions(function_name, nullptr, eFunctionNameTypeAuto, - include_symbols, include_inlines, sc_list); + module->FindFunctions(function_name, CompilerDeclContext(), + eFunctionNameTypeAuto, include_symbols, + include_inlines, sc_list); } num_matches = sc_list.GetSize(); if (num_matches) { @@ -2162,7 +2168,7 @@ protected: } }; -#pragma mark CommandObjectTargetModulesDumpSections +#pragma mark CommandObjectTargetModulesDumpClangAST // Clang AST dumping command @@ -2736,10 +2742,8 @@ protected: const char *load_addr_cstr = args.GetArgumentAtIndex(i + 1); if (sect_name && load_addr_cstr) { ConstString const_sect_name(sect_name); - bool success = false; - addr_t load_addr = StringConvert::ToUInt64( - load_addr_cstr, LLDB_INVALID_ADDRESS, 0, &success); - if (success) { + addr_t load_addr; + if (llvm::to_integer(load_addr_cstr, load_addr)) { SectionSP section_sp( section_list->FindSectionByName(const_sect_name)); if (section_sp) { @@ -3022,17 +3026,14 @@ protected: module_list_ptr = &target->GetImages(); } } else { - // TODO: Convert to entry based iteration. Requires converting - // FindModulesByName. - for (size_t i = 0; i < argc; ++i) { + for (const Args::ArgEntry &arg : command) { // Dump specified images (by basename or fullpath) - const char *arg_cstr = command.GetArgumentAtIndex(i); const size_t num_matches = FindModulesByName( - target, arg_cstr, module_list, use_global_module_list); + target, arg.c_str(), module_list, use_global_module_list); if (num_matches == 0) { if (argc == 1) { result.AppendErrorWithFormat("no modules found that match '%s'", - arg_cstr); + arg.c_str()); result.SetStatus(eReturnStatusFailed); return false; } @@ -3268,7 +3269,7 @@ public: switch (short_option) { case 'a': { - m_str = option_arg; + m_str = std::string(option_arg); m_type = eLookupTypeAddress; m_addr = OptionArgParser::ToAddress(execution_context, option_arg, LLDB_INVALID_ADDRESS, &error); @@ -3279,7 +3280,7 @@ public: } case 'n': - m_str = option_arg; + m_str = std::string(option_arg); m_type = eLookupTypeFunctionOrSymbol; break; @@ -3603,7 +3604,7 @@ public: break; case 's': - m_str = option_arg; + m_str = std::string(option_arg); m_type = eLookupTypeSymbol; break; @@ -3626,17 +3627,17 @@ public: break; case 'F': - m_str = option_arg; + m_str = std::string(option_arg); m_type = eLookupTypeFunction; break; case 'n': - m_str = option_arg; + m_str = std::string(option_arg); m_type = eLookupTypeFunctionOrSymbol; break; case 't': - m_str = option_arg; + m_str = std::string(option_arg); m_type = eLookupTypeType; break; @@ -3990,7 +3991,9 @@ public: private: // For CommandObjectTargetModules only - DISALLOW_COPY_AND_ASSIGN(CommandObjectTargetModules); + CommandObjectTargetModules(const CommandObjectTargetModules &) = delete; + const CommandObjectTargetModules & + operator=(const CommandObjectTargetModules &) = delete; }; class CommandObjectTargetSymbolsAdd : public CommandObjectParsed { @@ -3999,19 +4002,20 @@ public: : CommandObjectParsed( interpreter, "target symbols add", "Add a debug symbol file to one of the target's current modules by " - "specifying a path to a debug symbols file, or using the options " - "to specify a module to download symbols for.", + "specifying a path to a debug symbols file or by using the options " + "to specify a module.", "target symbols add <cmd-options> [<symfile>]", eCommandRequiresTarget), m_option_group(), m_file_option( LLDB_OPT_SET_1, false, "shlib", 's', CommandCompletions::eModuleCompletion, eArgTypeShlibName, - "Fullpath or basename for module to find debug symbols for."), + "Locate the debug symbols for the shared library specified by " + "name."), m_current_frame_option( LLDB_OPT_SET_2, false, "frame", 'F', - "Locate the debug symbols the currently selected frame.", false, - true) + "Locate the debug symbols for the currently selected frame.", + false, true) { m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL, @@ -4053,12 +4057,10 @@ protected: module_spec.GetFileSpec().GetFilename() = symbol_fspec.GetFilename(); } - // We now have a module that represents a symbol file that can be used - // for a module that might exist in the current target, so we need to - // find that module in the target - ModuleList matching_module_list; + // Now module_spec represents a symbol file for a module that might exist + // in the current target. Let's find possible matches. + ModuleList matching_modules; - size_t num_matches = 0; // First extract all module specs from the symbol file lldb_private::ModuleSpecList symfile_module_specs; if (ObjectFile::GetModuleSpecifications(module_spec.GetSymbolFileSpec(), @@ -4069,34 +4071,30 @@ protected: target_arch_module_spec.GetArchitecture() = target->GetArchitecture(); if (symfile_module_specs.FindMatchingModuleSpec(target_arch_module_spec, symfile_module_spec)) { - // See if it has a UUID? if (symfile_module_spec.GetUUID().IsValid()) { // It has a UUID, look for this UUID in the target modules ModuleSpec symfile_uuid_module_spec; symfile_uuid_module_spec.GetUUID() = symfile_module_spec.GetUUID(); target->GetImages().FindModules(symfile_uuid_module_spec, - matching_module_list); - num_matches = matching_module_list.GetSize(); + matching_modules); } } - if (num_matches == 0) { - // No matches yet, iterate through the module specs to find a UUID - // value that we can match up to an image in our target - const size_t num_symfile_module_specs = - symfile_module_specs.GetSize(); - for (size_t i = 0; i < num_symfile_module_specs && num_matches == 0; - ++i) { + if (matching_modules.IsEmpty()) { + // No matches yet. Iterate through the module specs to find a UUID + // value that we can match up to an image in our target. + const size_t num_symfile_module_specs = symfile_module_specs.GetSize(); + for (size_t i = 0; + i < num_symfile_module_specs && matching_modules.IsEmpty(); ++i) { if (symfile_module_specs.GetModuleSpecAtIndex( i, symfile_module_spec)) { if (symfile_module_spec.GetUUID().IsValid()) { - // It has a UUID, look for this UUID in the target modules + // It has a UUID. Look for this UUID in the target modules. ModuleSpec symfile_uuid_module_spec; symfile_uuid_module_spec.GetUUID() = symfile_module_spec.GetUUID(); target->GetImages().FindModules(symfile_uuid_module_spec, - matching_module_list); - num_matches = matching_module_list.GetSize(); + matching_modules); } } } @@ -4104,13 +4102,11 @@ protected: } // Just try to match up the file by basename if we have no matches at - // this point - if (num_matches == 0) { - target->GetImages().FindModules(module_spec, matching_module_list); - num_matches = matching_module_list.GetSize(); - } + // this point. For example, module foo might have symbols in foo.debug. + if (matching_modules.IsEmpty()) + target->GetImages().FindModules(module_spec, matching_modules); - while (num_matches == 0) { + while (matching_modules.IsEmpty()) { ConstString filename_no_extension( module_spec.GetFileSpec().GetFileNameStrippingExtension()); // Empty string returned, let's bail @@ -4123,17 +4119,20 @@ protected: // Replace basename with one fewer extension module_spec.GetFileSpec().GetFilename() = filename_no_extension; - target->GetImages().FindModules(module_spec, matching_module_list); - num_matches = matching_module_list.GetSize(); + target->GetImages().FindModules(module_spec, matching_modules); } - if (num_matches > 1) { + if (matching_modules.GetSize() > 1) { result.AppendErrorWithFormat("multiple modules match symbol file '%s', " "use the --uuid option to resolve the " "ambiguity.\n", symfile_path); - } else if (num_matches == 1) { - ModuleSP module_sp(matching_module_list.GetModuleAtIndex(0)); + result.SetStatus(eReturnStatusFailed); + return false; + } + + if (matching_modules.GetSize() == 1) { + ModuleSP module_sp(matching_modules.GetModuleAtIndex(0)); // The module has not yet created its symbol vendor, we can just give // the existing target module the symfile path to use for when it @@ -4144,7 +4143,6 @@ protected: module_sp->GetSymbolFile(true, &result.GetErrorStream()); if (symbol_file) { ObjectFile *object_file = symbol_file->GetObjectFile(); - if (object_file && object_file->GetFileSpec() == symbol_fspec) { // Provide feedback that the symfile has been successfully added. const FileSpec &module_fs = module_sp->GetFileSpec(); @@ -4163,7 +4161,7 @@ protected: Status error; StreamString feedback_stream; module_sp->LoadScriptingResourceInTarget(target, error, - &feedback_stream); + &feedback_stream); if (error.Fail() && error.AsCString()) result.AppendWarningWithFormat( "unable to load scripting data for module %s - error " @@ -4173,7 +4171,7 @@ protected: .GetCString(), error.AsCString()); else if (feedback_stream.GetSize()) - result.AppendWarningWithFormat("%s", feedback_stream.GetData()); + result.AppendWarning(feedback_stream.GetData()); flush = true; result.SetStatus(eReturnStatusSuccessFinishResult); @@ -4184,7 +4182,6 @@ protected: module_sp->SetSymbolFileFileSpec(FileSpec()); } - namespace fs = llvm::sys::fs; StreamString ss_symfile_uuid; if (module_spec.GetUUID().IsValid()) { ss_symfile_uuid << " ("; @@ -4194,7 +4191,7 @@ protected: result.AppendErrorWithFormat( "symbol file '%s'%s does not match any existing module%s\n", symfile_path, ss_symfile_uuid.GetData(), - !fs::is_regular_file(symbol_fspec.GetPath()) + !llvm::sys::fs::is_regular_file(symbol_fspec.GetPath()) ? "\n please specify the full path to the symbol file" : ""); result.SetStatus(eReturnStatusFailed); @@ -4394,7 +4391,9 @@ public: private: // For CommandObjectTargetModules only - DISALLOW_COPY_AND_ASSIGN(CommandObjectTargetSymbols); + CommandObjectTargetSymbols(const CommandObjectTargetSymbols &) = delete; + const CommandObjectTargetSymbols & + operator=(const CommandObjectTargetSymbols &) = delete; }; #pragma mark CommandObjectTargetStopHookAdd @@ -4427,7 +4426,7 @@ public: switch (short_option) { case 'c': - m_class_name = option_arg; + m_class_name = std::string(option_arg); m_sym_ctx_specified = true; break; @@ -4464,18 +4463,18 @@ public: break; case 'n': - m_function_name = option_arg; + m_function_name = std::string(option_arg); m_func_name_type_mask |= eFunctionNameTypeAuto; m_sym_ctx_specified = true; break; case 'f': - m_file_name = option_arg; + m_file_name = std::string(option_arg); m_sym_ctx_specified = true; break; case 's': - m_module_name = option_arg; + m_module_name = std::string(option_arg); m_sym_ctx_specified = true; break; @@ -4487,12 +4486,12 @@ public: break; case 'T': - m_thread_name = option_arg; + m_thread_name = std::string(option_arg); m_thread_specified = true; break; case 'q': - m_queue_name = option_arg; + m_queue_name = std::string(option_arg); m_thread_specified = true; break; @@ -4505,7 +4504,7 @@ public: case 'o': m_use_one_liner = true; - m_one_liner.push_back(option_arg); + m_one_liner.push_back(std::string(option_arg)); break; default: @@ -4615,8 +4614,8 @@ protected: // First step, make the specifier. std::unique_ptr<SymbolContextSpecifier> specifier_up; if (m_options.m_sym_ctx_specified) { - specifier_up.reset( - new SymbolContextSpecifier(GetDebugger().GetSelectedTarget())); + specifier_up = std::make_unique<SymbolContextSpecifier>( + GetDebugger().GetSelectedTarget()); if (!m_options.m_module_name.empty()) { specifier_up->AddSpecification( @@ -4725,18 +4724,15 @@ protected: target.RemoveAllStopHooks(); } } else { - bool success; for (size_t i = 0; i < num_args; i++) { - lldb::user_id_t user_id = StringConvert::ToUInt32( - command.GetArgumentAtIndex(i), 0, 0, &success); - if (!success) { + lldb::user_id_t user_id; + if (!llvm::to_integer(command.GetArgumentAtIndex(i), user_id)) { result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i)); result.SetStatus(eReturnStatusFailed); return false; } - success = target.RemoveStopHookByID(user_id); - if (!success) { + if (!target.RemoveStopHookByID(user_id)) { result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i)); result.SetStatus(eReturnStatusFailed); @@ -4774,9 +4770,8 @@ protected: target.SetAllStopHooksActiveState(m_enable); } else { for (size_t i = 0; i < num_args; i++) { - lldb::user_id_t user_id = StringConvert::ToUInt32( - command.GetArgumentAtIndex(i), 0, 0, &success); - if (!success) { + lldb::user_id_t user_id; + if (!llvm::to_integer(command.GetArgumentAtIndex(i), user_id)) { result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i)); result.SetStatus(eReturnStatusFailed); @@ -4881,6 +4876,9 @@ CommandObjectMultiwordTarget::CommandObjectMultiwordTarget( CommandObjectSP(new CommandObjectTargetList(interpreter))); LoadSubCommand("select", CommandObjectSP(new CommandObjectTargetSelect(interpreter))); + LoadSubCommand("show-launch-environment", + CommandObjectSP(new CommandObjectTargetShowLaunchEnvironment( + interpreter))); LoadSubCommand( "stop-hook", CommandObjectSP(new CommandObjectMultiwordTargetStopHooks(interpreter))); diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectTarget.h b/contrib/llvm-project/lldb/source/Commands/CommandObjectTarget.h index bf1dae6bfdc1..94afc00064c8 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectTarget.h +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectTarget.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CommandObjectTarget_h_ -#define liblldb_CommandObjectTarget_h_ +#ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTTARGET_H +#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTTARGET_H #include "lldb/Interpreter/CommandObjectMultiword.h" @@ -24,4 +24,4 @@ public: } // namespace lldb_private -#endif // liblldb_CommandObjectTarget_h_ +#endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTTARGET_H diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectThread.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectThread.cpp index 83c7cb50d142..f0ad1798fec6 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectThread.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectThread.cpp @@ -1,4 +1,4 @@ -//===-- CommandObjectThread.cpp ---------------------------------*- C++ -*-===// +//===-- CommandObjectThread.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -10,7 +10,6 @@ #include "lldb/Core/ValueObject.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" @@ -109,11 +108,8 @@ public: process->GetThreadList().GetMutex()); for (size_t i = 0; i < num_args; i++) { - bool success; - - uint32_t thread_idx = StringConvert::ToUInt32( - command.GetArgumentAtIndex(i), 0, 0, &success); - if (!success) { + uint32_t thread_idx; + if (!llvm::to_integer(command.GetArgumentAtIndex(i), thread_idx)) { result.AppendErrorWithFormat("invalid thread specification: \"%s\"\n", command.GetArgumentAtIndex(i)); result.SetStatus(eReturnStatusFailed); @@ -464,12 +460,12 @@ public: case 'r': m_avoid_regexp.clear(); - m_avoid_regexp.assign(option_arg); + m_avoid_regexp.assign(std::string(option_arg)); break; case 't': m_step_in_target.clear(); - m_step_in_target.assign(option_arg); + m_step_in_target.assign(std::string(option_arg)); break; default: @@ -565,9 +561,9 @@ protected: } } else { const char *thread_idx_cstr = command.GetArgumentAtIndex(0); - uint32_t step_thread_idx = - StringConvert::ToUInt32(thread_idx_cstr, LLDB_INVALID_INDEX32); - if (step_thread_idx == LLDB_INVALID_INDEX32) { + uint32_t step_thread_idx; + + if (!llvm::to_integer(thread_idx_cstr, step_thread_idx)) { result.AppendErrorWithFormat("invalid thread index '%s'.\n", thread_idx_cstr); result.SetStatus(eReturnStatusFailed); @@ -775,7 +771,6 @@ protected: return result.Succeeded(); } -protected: StepType m_step_type; StepScope m_step_scope; ThreadStepScopeOptionGroup m_options; @@ -1096,9 +1091,7 @@ protected: size_t num_args = command.GetArgumentCount(); for (size_t i = 0; i < num_args; i++) { uint32_t line_number; - line_number = StringConvert::ToUInt32(command.GetArgumentAtIndex(i), - UINT32_MAX); - if (line_number == UINT32_MAX) { + if (!llvm::to_integer(command.GetArgumentAtIndex(i), line_number)) { result.AppendErrorWithFormat("invalid line number: '%s'.\n", command.GetArgumentAtIndex(i)); result.SetStatus(eReturnStatusFailed); @@ -1322,8 +1315,13 @@ protected: return false; } - uint32_t index_id = - StringConvert::ToUInt32(command.GetArgumentAtIndex(0), 0, 0); + uint32_t index_id; + if (!llvm::to_integer(command.GetArgumentAtIndex(0), index_id)) { + result.AppendErrorWithFormat("Invalid thread index '%s'", + command.GetArgumentAtIndex(0)); + result.SetStatus(eReturnStatusFailed); + return false; + } Thread *new_thread = process->GetThreadList().FindThreadByIndexID(index_id).get(); @@ -1833,25 +1831,36 @@ public: 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 'i': m_internal = true; break; + case 't': + lldb::tid_t tid; + if (option_arg.getAsInteger(0, tid)) + return Status("invalid tid: '%s'.", option_arg.str().c_str()); + m_tids.push_back(tid); + break; + case 'u': + m_unreported = false; + break; case 'v': m_verbose = true; break; default: llvm_unreachable("Unimplemented option"); } - return error; + return {}; } void OptionParsingStarting(ExecutionContext *execution_context) override { m_verbose = false; m_internal = false; + m_unreported = true; // The variable is "skip unreported" and we want to + // skip unreported by default. + m_tids.clear(); } llvm::ArrayRef<OptionDefinition> GetDefinitions() override { @@ -1861,6 +1870,8 @@ public: // Instance variables to hold the values for command options. bool m_verbose; bool m_internal; + bool m_unreported; + std::vector<lldb::tid_t> m_tids; }; CommandObjectThreadPlanList(CommandInterpreter &interpreter) @@ -1879,25 +1890,59 @@ public: Options *GetOptions() override { return &m_options; } + bool DoExecute(Args &command, CommandReturnObject &result) override { + // If we are reporting all threads, dispatch to the Process to do that: + if (command.GetArgumentCount() == 0 && m_options.m_tids.empty()) { + Stream &strm = result.GetOutputStream(); + DescriptionLevel desc_level = m_options.m_verbose + ? eDescriptionLevelVerbose + : eDescriptionLevelFull; + m_exe_ctx.GetProcessPtr()->DumpThreadPlans( + strm, desc_level, m_options.m_internal, true, m_options.m_unreported); + result.SetStatus(eReturnStatusSuccessFinishResult); + return true; + } else { + // Do any TID's that the user may have specified as TID, then do any + // Thread Indexes... + if (!m_options.m_tids.empty()) { + Process *process = m_exe_ctx.GetProcessPtr(); + StreamString tmp_strm; + for (lldb::tid_t tid : m_options.m_tids) { + bool success = process->DumpThreadPlansForTID( + tmp_strm, tid, eDescriptionLevelFull, m_options.m_internal, + true /* condense_trivial */, m_options.m_unreported); + // If we didn't find a TID, stop here and return an error. + if (!success) { + result.SetError("Error dumping plans:"); + result.AppendError(tmp_strm.GetString()); + result.SetStatus(eReturnStatusFailed); + return false; + } + // Otherwise, add our data to the output: + result.GetOutputStream() << tmp_strm.GetString(); + } + } + return CommandObjectIterateOverThreads::DoExecute(command, result); + } + } + protected: bool HandleOneThread(lldb::tid_t tid, CommandReturnObject &result) override { - ThreadSP thread_sp = - m_exe_ctx.GetProcessPtr()->GetThreadList().FindThreadByID(tid); - if (!thread_sp) { - result.AppendErrorWithFormat("thread no longer exists: 0x%" PRIx64 "\n", - tid); - result.SetStatus(eReturnStatusFailed); - return false; - } + // If we have already handled this from a -t option, skip it here. + if (std::find(m_options.m_tids.begin(), m_options.m_tids.end(), tid) != + m_options.m_tids.end()) + return true; - Thread *thread = thread_sp.get(); + Process *process = m_exe_ctx.GetProcessPtr(); Stream &strm = result.GetOutputStream(); DescriptionLevel desc_level = eDescriptionLevelFull; if (m_options.m_verbose) desc_level = eDescriptionLevelVerbose; - thread->DumpThreadPlans(&strm, desc_level, m_options.m_internal, true); + process->DumpThreadPlansForTID(strm, tid, desc_level, m_options.m_internal, + true /* condense_trivial */, + m_options.m_unreported); return true; } @@ -1943,10 +1988,8 @@ public: return false; } - bool success; - uint32_t thread_plan_idx = - StringConvert::ToUInt32(args.GetArgumentAtIndex(0), 0, 0, &success); - if (!success) { + uint32_t thread_plan_idx; + if (!llvm::to_integer(args.GetArgumentAtIndex(0), thread_plan_idx)) { result.AppendErrorWithFormat( "Invalid thread index: \"%s\" - should be unsigned int.", args.GetArgumentAtIndex(0)); @@ -1974,6 +2017,71 @@ public: } }; +class CommandObjectThreadPlanPrune : public CommandObjectParsed { +public: + CommandObjectThreadPlanPrune(CommandInterpreter &interpreter) + : CommandObjectParsed(interpreter, "thread plan prune", + "Removes any thread plans associated with " + "currently unreported threads. " + "Specify one or more TID's to remove, or if no " + "TID's are provides, remove threads for all " + "unreported threads", + nullptr, + eCommandRequiresProcess | + eCommandTryTargetAPILock | + eCommandProcessMustBeLaunched | + eCommandProcessMustBePaused) { + CommandArgumentEntry arg; + CommandArgumentData tid_arg; + + // Define the first (and only) variant of this arg. + tid_arg.arg_type = eArgTypeThreadID; + tid_arg.arg_repetition = eArgRepeatStar; + + // There is only one variant this argument could be; put it into the + // argument entry. + arg.push_back(tid_arg); + + // Push the data for the first argument into the m_arguments vector. + m_arguments.push_back(arg); + } + + ~CommandObjectThreadPlanPrune() override = default; + + bool DoExecute(Args &args, CommandReturnObject &result) override { + Process *process = m_exe_ctx.GetProcessPtr(); + + if (args.GetArgumentCount() == 0) { + process->PruneThreadPlans(); + result.SetStatus(eReturnStatusSuccessFinishNoResult); + return true; + } + + const size_t num_args = args.GetArgumentCount(); + + std::lock_guard<std::recursive_mutex> guard( + process->GetThreadList().GetMutex()); + + for (size_t i = 0; i < num_args; i++) { + lldb::tid_t tid; + if (!llvm::to_integer(args.GetArgumentAtIndex(i), tid)) { + result.AppendErrorWithFormat("invalid thread specification: \"%s\"\n", + args.GetArgumentAtIndex(i)); + result.SetStatus(eReturnStatusFailed); + return false; + } + if (!process->PruneThreadPlansForTID(tid)) { + result.AppendErrorWithFormat("Could not find unreported tid: \"%s\"\n", + args.GetArgumentAtIndex(i)); + result.SetStatus(eReturnStatusFailed); + return false; + } + } + result.SetStatus(eReturnStatusSuccessFinishNoResult); + return true; + } +}; + // CommandObjectMultiwordThreadPlan class CommandObjectMultiwordThreadPlan : public CommandObjectMultiword { @@ -1988,6 +2096,9 @@ public: LoadSubCommand( "discard", CommandObjectSP(new CommandObjectThreadPlanDiscard(interpreter))); + LoadSubCommand( + "prune", + CommandObjectSP(new CommandObjectThreadPlanPrune(interpreter))); } ~CommandObjectMultiwordThreadPlan() override = default; diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectThread.h b/contrib/llvm-project/lldb/source/Commands/CommandObjectThread.h index 77729ceecd63..3ca6a2159501 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectThread.h +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectThread.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CommandObjectThread_h_ -#define liblldb_CommandObjectThread_h_ +#ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTTHREAD_H +#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTTHREAD_H #include "lldb/Interpreter/CommandObjectMultiword.h" @@ -22,4 +22,4 @@ public: } // namespace lldb_private -#endif // liblldb_CommandObjectThread_h_ +#endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTTHREAD_H diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectType.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectType.cpp index 87c107cfb943..b2020f26621f 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectType.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectType.cpp @@ -1,4 +1,4 @@ -//===-- CommandObjectType.cpp -----------------------------------*- C++ -*-===// +//===-- CommandObjectType.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -531,7 +531,7 @@ private: m_skip_pointers = true; break; case 'w': - m_category.assign(option_value); + m_category.assign(std::string(option_value)); break; case 'r': m_skip_references = true; @@ -540,7 +540,7 @@ private: m_regex = true; break; case 't': - m_custom_type_name.assign(option_value); + m_custom_type_name.assign(std::string(option_value)); break; default: llvm_unreachable("Unimplemented option"); @@ -1031,8 +1031,8 @@ protected: std::unique_ptr<RegularExpression> formatter_regex; if (m_options.m_category_regex.OptionWasSet()) { - category_regex.reset(new RegularExpression( - m_options.m_category_regex.GetCurrentValueAsRef())); + category_regex = std::make_unique<RegularExpression>( + m_options.m_category_regex.GetCurrentValueAsRef()); if (!category_regex->IsValid()) { result.AppendErrorWithFormat( "syntax error in category regular expression '%s'", @@ -1044,8 +1044,8 @@ protected: if (argc == 1) { const char *arg = command.GetArgumentAtIndex(0); - formatter_regex.reset( - new RegularExpression(llvm::StringRef::withNullAsEmpty(arg))); + formatter_regex = std::make_unique<RegularExpression>( + llvm::StringRef::withNullAsEmpty(arg)); if (!formatter_regex->IsValid()) { result.AppendErrorWithFormat("syntax error in regular expression '%s'", arg); @@ -1206,11 +1206,11 @@ Status CommandObjectTypeSummaryAdd::CommandOptions::SetOptionValue( m_name.SetString(option_arg); break; case 'o': - m_python_script = option_arg; + m_python_script = std::string(option_arg); m_is_add_script = true; break; case 'F': - m_python_function = option_arg; + m_python_function = std::string(option_arg); m_is_add_script = true; break; case 'P': @@ -1326,7 +1326,7 @@ bool CommandObjectTypeSummaryAdd::Execute_ScriptSummary( return false; } - options->m_target_types << entry.ref(); + options->m_target_types << std::string(entry.ref()); } m_interpreter.GetPythonCommandsFromIOHandler( @@ -2092,7 +2092,8 @@ protected: if (argc == 1) { const char *arg = command.GetArgumentAtIndex(0); - regex.reset(new RegularExpression(llvm::StringRef::withNullAsEmpty(arg))); + regex = std::make_unique<RegularExpression>( + llvm::StringRef::withNullAsEmpty(arg)); if (!regex->IsValid()) { result.AppendErrorWithFormat( "syntax error in category regular expression '%s'", arg); @@ -2225,7 +2226,7 @@ bool CommandObjectTypeSynthAdd::Execute_HandwritePython( return false; } - options->m_target_types << entry.ref(); + options->m_target_types << std::string(entry.ref()); } m_interpreter.GetPythonCommandsFromIOHandler( @@ -2390,7 +2391,7 @@ private: option_arg.str().c_str()); break; case 'c': - m_expr_paths.push_back(option_arg); + m_expr_paths.push_back(std::string(option_arg)); has_child_list = true; break; case 'p': @@ -2705,7 +2706,7 @@ public: return true; }); - m_cmd_help_long = stream.GetString(); + m_cmd_help_long = std::string(stream.GetString()); return m_cmd_help_long; } diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectType.h b/contrib/llvm-project/lldb/source/Commands/CommandObjectType.h index 938e481a6b87..1c081abe2be4 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectType.h +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectType.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CommandObjectType_h_ -#define liblldb_CommandObjectType_h_ +#ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTTYPE_H +#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTTYPE_H #include "lldb/Interpreter/CommandObjectMultiword.h" @@ -22,4 +22,4 @@ public: } // namespace lldb_private -#endif // liblldb_CommandObjectType_h_ +#endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTTYPE_H diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectVersion.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectVersion.cpp index 227d5d132d96..065cbe4660d3 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectVersion.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectVersion.cpp @@ -1,4 +1,4 @@ -//===-- CommandObjectVersion.cpp --------------------------------*- C++ -*-===// +//===-- CommandObjectVersion.cpp ------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectVersion.h b/contrib/llvm-project/lldb/source/Commands/CommandObjectVersion.h index 30f44aeb1658..dce1a8d67b88 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectVersion.h +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectVersion.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CommandObjectVersion_h_ -#define liblldb_CommandObjectVersion_h_ +#ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTVERSION_H +#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTVERSION_H #include "lldb/Interpreter/CommandObject.h" @@ -27,4 +27,4 @@ protected: } // namespace lldb_private -#endif // liblldb_CommandObjectVersion_h_ +#endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTVERSION_H diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectWatchpoint.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectWatchpoint.cpp index c965d354f734..ce4662930a7c 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectWatchpoint.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectWatchpoint.cpp @@ -1,4 +1,4 @@ -//===-- CommandObjectWatchpoint.cpp -----------------------------*- C++ -*-===// +//===-- CommandObjectWatchpoint.cpp ---------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -41,7 +41,7 @@ static bool CheckTargetForWatchpointOperations(Target *target, bool process_is_valid = target->GetProcessSP() && target->GetProcessSP()->IsAlive(); if (!process_is_valid) { - result.AppendError("Thre's no process or it is not alive."); + result.AppendError("There's no process or it is not alive."); result.SetStatus(eReturnStatusFailed); return false; } @@ -692,7 +692,7 @@ public: switch (short_option) { case 'c': - m_condition = option_arg; + m_condition = std::string(option_arg); m_condition_passed = true; break; default: @@ -934,7 +934,7 @@ protected: StreamString ss; // True to show fullpath for declaration file. var_sp->GetDeclaration().DumpStopContext(&ss, true); - wp->SetDeclInfo(ss.GetString()); + wp->SetDeclInfo(std::string(ss.GetString())); } output_stream.Printf("Watchpoint created: "); wp->GetDescription(&output_stream, lldb::eDescriptionLevelFull); @@ -1038,7 +1038,7 @@ protected: // set a watchpoint. if (raw_command.trim().empty()) { result.GetErrorStream().Printf("error: required argument missing; " - "specify an expression to evaulate into " + "specify an expression to evaluate into " "the address to watch for\n"); result.SetStatus(eReturnStatusFailed); return false; @@ -1070,6 +1070,8 @@ protected: result.GetErrorStream().Printf( "error: expression evaluation of address to watch failed\n"); result.GetErrorStream() << "expression evaluated: \n" << expr << "\n"; + if (valobj_sp && !valobj_sp->GetError().Success()) + result.GetErrorStream() << valobj_sp->GetError().AsCString() << "\n"; result.SetStatus(eReturnStatusFailed); return false; } diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectWatchpoint.h b/contrib/llvm-project/lldb/source/Commands/CommandObjectWatchpoint.h index 4f4f80bbd620..87f9f4383bd2 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectWatchpoint.h +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectWatchpoint.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CommandObjectWatchpoint_h_ -#define liblldb_CommandObjectWatchpoint_h_ +#ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTWATCHPOINT_H +#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTWATCHPOINT_H #include "lldb/Interpreter/CommandObjectMultiword.h" #include "lldb/Interpreter/OptionGroupWatchpoint.h" @@ -28,4 +28,4 @@ public: } // namespace lldb_private -#endif // liblldb_CommandObjectWatchpoint_h_ +#endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTWATCHPOINT_H diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectWatchpointCommand.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectWatchpointCommand.cpp index 1b83e885d27e..fe3052a775a2 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectWatchpointCommand.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectWatchpointCommand.cpp @@ -1,4 +1,4 @@ -//===-- CommandObjectWatchpointCommand.cpp ----------------------*- C++ -*-===// +//===-- CommandObjectWatchpointCommand.cpp --------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -39,7 +39,7 @@ static constexpr OptionEnumValueElement g_script_option_enumeration[] = { { eScriptLanguageLua, "lua", - "Commands are in the Python language.", + "Commands are in the Lua language.", }, { eSortOrderByName, @@ -282,12 +282,12 @@ are no syntax errors may indicate that a function was declared but never called. ExecutionContext exe_ctx(context->exe_ctx_ref); Target *target = exe_ctx.GetTargetPtr(); if (target) { - CommandReturnObject result; Debugger &debugger = target->GetDebugger(); + CommandReturnObject result(debugger.GetUseColor()); + // Rig up the results secondary output stream to the debugger's, so the // output will come out synchronously if the debugger is set up that // way. - StreamSP output_stream(debugger.GetAsyncOutputStream()); StreamSP error_stream(debugger.GetAsyncErrorStream()); result.SetImmediateOutputStream(output_stream); @@ -327,7 +327,7 @@ are no syntax errors may indicate that a function was declared but never called. switch (short_option) { case 'o': m_use_one_liner = true; - m_one_liner = option_arg; + m_one_liner = std::string(option_arg); break; case 's': @@ -359,7 +359,7 @@ are no syntax errors may indicate that a function was declared but never called. case 'F': m_use_one_liner = false; - m_function_name.assign(option_arg); + m_function_name.assign(std::string(option_arg)); break; default: diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectWatchpointCommand.h b/contrib/llvm-project/lldb/source/Commands/CommandObjectWatchpointCommand.h index 6fbc9c741617..b3cb70d08985 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectWatchpointCommand.h +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectWatchpointCommand.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CommandObjectWatchpointCommand_h_ -#define liblldb_CommandObjectWatchpointCommand_h_ +#ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTWATCHPOINTCOMMAND_H +#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTWATCHPOINTCOMMAND_H #include "lldb/Interpreter/CommandObjectMultiword.h" @@ -24,4 +24,4 @@ public: } // namespace lldb_private -#endif // liblldb_CommandObjectWatchpointCommand_h_ +#endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTWATCHPOINTCOMMAND_H diff --git a/contrib/llvm-project/lldb/source/Commands/Options.td b/contrib/llvm-project/lldb/source/Commands/Options.td index 850df133a429..d6f1e0a3c96d 100644 --- a/contrib/llvm-project/lldb/source/Commands/Options.td +++ b/contrib/llvm-project/lldb/source/Commands/Options.td @@ -39,6 +39,11 @@ let Command = "settings read" in { Desc<"The file from which to read the settings.">; } +let Command = "settings clear" in { + def setclear_all : Option<"all", "a">, + Desc<"Clear all settings.">; +} + let Command = "breakpoint list" in { // FIXME: We need to add an "internal" command, and then add this sort of // thing to it. But I need to see it for now, and don't want to wait. @@ -115,6 +120,8 @@ let Command = "breakpoint set" in { def breakpoint_set_line : Option<"line", "l">, Group<1>, Arg<"LineNum">, Required, Desc<"Specifies the line number on which to set this breakpoint.">; + def breakpoint_set_column : Option<"column", "u">, Group<1>, Arg<"ColumnNum">, + Desc<"Specifies the column number on which to set this breakpoint.">; def breakpoint_set_address : Option<"address", "a">, Group<2>, Arg<"AddressOrExpression">, Required, Desc<"Set the breakpoint at the specified address. If the address maps " @@ -150,7 +157,7 @@ let Command = "breakpoint set" in { "multiple times tomake one breakpoint for multiple methods.">; def breakpoint_set_func_regex : Option<"func-regex", "r">, Group<7>, Arg<"RegularExpression">, Required, Desc<"Set the breakpoint by function " - "name, evaluating a regular-expression to findthe function name(s).">; + "name, evaluating a regular-expression to find the function name(s).">; def breakpoint_set_basename : Option<"basename", "b">, Group<8>, Arg<"FunctionName">, Required, Completion<"Symbol">, Desc<"Set the breakpoint by function basename (C++ namespaces and arguments" @@ -304,7 +311,7 @@ let Command = "disassemble" in { Desc<"Address at which to start disassembling.">; def disassemble_options_end_address : Option<"end-address", "e">, Group<1>, Arg<"AddressOrExpression">, Desc<"Address at which to end disassembling.">; - def disassemble_options_count : Option<"count", "c">, Groups<[2,3,4,5]>, + def disassemble_options_count : Option<"count", "c">, Groups<[2,3,4,5,7]>, Arg<"NumLines">, Desc<"Number of instructions to display.">; def disassemble_options_name : Option<"name", "n">, Group<3>, Arg<"FunctionName">, Completion<"Symbol">, @@ -319,6 +326,8 @@ let Command = "disassemble" in { def disassemble_options_address : Option<"address", "a">, Group<7>, Arg<"AddressOrExpression">, Desc<"Disassemble function containing this address.">; + def disassemble_options_force : Option<"force", "\\x01">, Groups<[2,3,4,5,7]>, + Desc<"Force dissasembly of large functions.">; } let Command = "expression" in { @@ -382,7 +391,8 @@ let Command = "frame recognizer add" in { "to.">; def frame_recognizer_function : Option<"function", "n">, Arg<"Name">, Completion<"Symbol">, - Desc<"Name of the function that this recognizer applies to.">; + Desc<"Name of the function that this recognizer applies to. " + "Can be specified more than once except if -x|--regex is provided.">; def frame_recognizer_python_class : Option<"python-class", "l">, Group<2>, Arg<"PythonClass">, Desc<"Give the name of a Python class to use for this frame recognizer.">; @@ -614,6 +624,8 @@ let Command = "platform process attach" in { } let Command = "platform shell" in { + def platform_shell_host : Option<"host", "h">, + Desc<"Run the commands on the host shell when enabled.">; def platform_shell_timeout : Option<"timeout", "t">, Arg<"Value">, Desc<"Seconds to wait for the remote host to finish running the command.">; } @@ -668,6 +680,11 @@ let Command = "process handle" in { Desc<"Whether or not the signal should be passed to the process.">; } +let Command = "process status" in { + def process_status_verbose : Option<"verbose", "v">, Group<1>, + Desc<"Show verbose process status including extended crash information.">; +} + let Command = "script import" in { def script_import_allow_reload : Option<"allow-reload", "r">, Group<1>, Desc<"Allow the script to be loaded even if it was already loaded before. " @@ -688,6 +705,7 @@ let Command = "script add" in { Desc<"Set the synchronicity of this command's executions with regard to " "LLDB event system.">; } + let Command = "source info" in { def source_info_count : Option<"count", "c">, Arg<"Count">, Desc<"The number of line entries to display.">; @@ -956,6 +974,11 @@ let Command = "thread plan list" in { Desc<"Display more information about the thread plans">; def thread_plan_list_internal : Option<"internal", "i">, Group<1>, Desc<"Display internal as well as user thread plans">; + def thread_plan_list_thread_id : Option<"thread-id", "t">, Group<1>, + Arg<"ThreadID">, Desc<"List the thread plans for this TID, can be " + "specified more than once.">; + def thread_plan_list_unreported : Option<"unreported", "u">, Group<1>, + Desc<"Display thread plans for unreported threads">; } let Command = "type summary add" in { |