diff options
Diffstat (limited to 'lldb/source/Commands/CommandObjectTarget.cpp')
| -rw-r--r-- | lldb/source/Commands/CommandObjectTarget.cpp | 388 | 
1 files changed, 266 insertions, 122 deletions
| diff --git a/lldb/source/Commands/CommandObjectTarget.cpp b/lldb/source/Commands/CommandObjectTarget.cpp index b25514b1ffbc..2a42eb22938d 100644 --- a/lldb/source/Commands/CommandObjectTarget.cpp +++ b/lldb/source/Commands/CommandObjectTarget.cpp @@ -272,7 +272,7 @@ protected:      if (core_file) {        auto file = FileSystem::Instance().Open( -          core_file, lldb_private::File::eOpenOptionRead); +          core_file, lldb_private::File::eOpenOptionReadOnly);        if (!file) {          result.AppendErrorWithFormatv("Cannot open '{0}': {1}.", @@ -286,7 +286,7 @@ protected:        FileSpec symfile(m_symbol_file.GetOptionValue().GetCurrentValue());        if (symfile) {          auto file = FileSystem::Instance().Open( -            symfile, lldb_private::File::eOpenOptionRead); +            symfile, lldb_private::File::eOpenOptionReadOnly);          if (!file) {            result.AppendErrorWithFormatv("Cannot open '{0}': {1}.", @@ -1047,8 +1047,7 @@ protected:            }            bool last_pair = ((argc - i) == 2);            target->GetImageSearchPathList().Append( -              ConstString(from), ConstString(to), -              last_pair); // Notify if this is the last pair +              from, to, last_pair); // Notify if this is the last pair            result.SetStatus(eReturnStatusSuccessFinishNoResult);          } else {            if (from[0]) @@ -1175,8 +1174,8 @@ protected:          if (from[0] && to[0]) {            bool last_pair = ((argc - i) == 2); -          target->GetImageSearchPathList().Insert( -              ConstString(from), ConstString(to), insert_idx, last_pair); +          target->GetImageSearchPathList().Insert(from, to, insert_idx, +                                                  last_pair);            result.SetStatus(eReturnStatusSuccessFinishNoResult);          } else {            if (from[0]) @@ -1570,20 +1569,18 @@ static void DumpSymbolContextList(ExecutionContextScope *exe_scope,  static size_t LookupFunctionInModule(CommandInterpreter &interpreter,                                       Stream &strm, Module *module,                                       const char *name, bool name_is_regex, -                                     bool include_inlines, bool include_symbols, +                                     const ModuleFunctionSearchOptions &options,                                       bool verbose) {    if (module && name && name[0]) {      SymbolContextList sc_list;      size_t num_matches = 0;      if (name_is_regex) {        RegularExpression function_name_regex((llvm::StringRef(name))); -      module->FindFunctions(function_name_regex, include_symbols, -                            include_inlines, sc_list); +      module->FindFunctions(function_name_regex, options, sc_list);      } else {        ConstString function_name(name);        module->FindFunctions(function_name, CompilerDeclContext(), -                            eFunctionNameTypeAuto, include_symbols, -                            include_inlines, sc_list); +                            eFunctionNameTypeAuto, options, sc_list);      }      num_matches = sc_list.GetSize();      if (num_matches) { @@ -2836,6 +2833,7 @@ protected:    OptionGroupUInt64 m_slide_option;  }; +#pragma mark CommandObjectTargetModulesList  // List images with associated information  #define LLDB_OPTIONS_target_modules_list  #include "CommandOptions.inc" @@ -3281,8 +3279,11 @@ protected:      if (m_options.m_type == eLookupTypeFunctionOrSymbol) {        ConstString function_name(m_options.m_str.c_str()); +      ModuleFunctionSearchOptions function_options; +      function_options.include_symbols = true; +      function_options.include_inlines = false;        target->GetImages().FindFunctions(function_name, eFunctionNameTypeAuto, -                                        true, false, sc_list); +                                        function_options, sc_list);      } else if (m_options.m_type == eLookupTypeAddress && target) {        Address addr;        if (target->GetSectionLoadList().ResolveLoadAddress(m_options.m_addr, @@ -3753,13 +3754,15 @@ public:      case eLookupTypeFunctionOrSymbol:      case eLookupTypeFunction:        if (!m_options.m_str.empty()) { -        if (LookupFunctionInModule( -                m_interpreter, result.GetOutputStream(), module, -                m_options.m_str.c_str(), m_options.m_use_regex, -                m_options.m_include_inlines, -                m_options.m_type == -                    eLookupTypeFunctionOrSymbol, // include symbols -                m_options.m_verbose)) { +        ModuleFunctionSearchOptions function_options; +        function_options.include_symbols = +            m_options.m_type == eLookupTypeFunctionOrSymbol; +        function_options.include_inlines = m_options.m_include_inlines; + +        if (LookupFunctionInModule(m_interpreter, result.GetOutputStream(), +                                   module, m_options.m_str.c_str(), +                                   m_options.m_use_regex, function_options, +                                   m_options.m_verbose)) {            result.SetStatus(eReturnStatusSuccessFinishResult);            return true;          } @@ -3959,8 +3962,12 @@ public:              "name."),          m_current_frame_option(              LLDB_OPT_SET_2, false, "frame", 'F', -            "Locate the debug symbols for the currently selected frame.", -            false, true) +            "Locate the debug symbols for the currently selected frame.", false, +            true), +        m_current_stack_option(LLDB_OPT_SET_2, false, "stack", 'S', +                               "Locate the debug symbols for every frame in " +                               "the current call stack.", +                               false, true)    {      m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL, @@ -3968,6 +3975,8 @@ public:      m_option_group.Append(&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);      m_option_group.Append(&m_current_frame_option, LLDB_OPT_SET_2,                            LLDB_OPT_SET_2); +    m_option_group.Append(&m_current_stack_option, LLDB_OPT_SET_2, +                          LLDB_OPT_SET_2);      m_option_group.Finalize();    } @@ -4140,6 +4149,167 @@ protected:      return false;    } +  bool DownloadObjectAndSymbolFile(ModuleSpec &module_spec, +                                   CommandReturnObject &result, bool &flush) { +    if (Symbols::DownloadObjectAndSymbolFile(module_spec)) { +      if (module_spec.GetSymbolFileSpec()) +        return AddModuleSymbols(m_exe_ctx.GetTargetPtr(), module_spec, flush, +                                result); +    } +    return false; +  } + +  bool AddSymbolsForUUID(CommandReturnObject &result, bool &flush) { +    assert(m_uuid_option_group.GetOptionValue().OptionWasSet()); + +    ModuleSpec module_spec; +    module_spec.GetUUID() = +        m_uuid_option_group.GetOptionValue().GetCurrentValue(); + +    if (!DownloadObjectAndSymbolFile(module_spec, result, flush)) { +      StreamString error_strm; +      error_strm.PutCString("unable to find debug symbols for UUID "); +      module_spec.GetUUID().Dump(&error_strm); +      result.AppendError(error_strm.GetString()); +      return false; +    } + +    return true; +  } + +  bool AddSymbolsForFile(CommandReturnObject &result, bool &flush) { +    assert(m_file_option.GetOptionValue().OptionWasSet()); + +    ModuleSpec module_spec; +    module_spec.GetFileSpec() = +        m_file_option.GetOptionValue().GetCurrentValue(); + +    Target *target = m_exe_ctx.GetTargetPtr(); +    ModuleSP module_sp(target->GetImages().FindFirstModule(module_spec)); +    if (module_sp) { +      module_spec.GetFileSpec() = module_sp->GetFileSpec(); +      module_spec.GetPlatformFileSpec() = module_sp->GetPlatformFileSpec(); +      module_spec.GetUUID() = module_sp->GetUUID(); +      module_spec.GetArchitecture() = module_sp->GetArchitecture(); +    } else { +      module_spec.GetArchitecture() = target->GetArchitecture(); +    } + +    if (!DownloadObjectAndSymbolFile(module_spec, result, flush)) { +      StreamString error_strm; +      error_strm.PutCString( +          "unable to find debug symbols for the executable file "); +      error_strm << module_spec.GetFileSpec(); +      result.AppendError(error_strm.GetString()); +      return false; +    } + +    return true; +  } + +  bool AddSymbolsForFrame(CommandReturnObject &result, bool &flush) { +    assert(m_current_frame_option.GetOptionValue().OptionWasSet()); + +    Process *process = m_exe_ctx.GetProcessPtr(); +    if (!process) { +      result.AppendError( +          "a process must exist in order to use the --frame option"); +      return false; +    } + +    const StateType process_state = process->GetState(); +    if (!StateIsStoppedState(process_state, true)) { +      result.AppendErrorWithFormat("process is not stopped: %s", +                                   StateAsCString(process_state)); +      return false; +    } + +    StackFrame *frame = m_exe_ctx.GetFramePtr(); +    if (!frame) { +      result.AppendError("invalid current frame"); +      return false; +    } + +    ModuleSP frame_module_sp( +        frame->GetSymbolContext(eSymbolContextModule).module_sp); +    if (!frame_module_sp) { +      result.AppendError("frame has no module"); +      return false; +    } + +    ModuleSpec module_spec; +    module_spec.GetUUID() = frame_module_sp->GetUUID(); + +    if (FileSystem::Instance().Exists(frame_module_sp->GetPlatformFileSpec())) { +      module_spec.GetArchitecture() = frame_module_sp->GetArchitecture(); +      module_spec.GetFileSpec() = frame_module_sp->GetPlatformFileSpec(); +    } + +    if (!DownloadObjectAndSymbolFile(module_spec, result, flush)) { +      result.AppendError("unable to find debug symbols for the current frame"); +      return false; +    } + +    return true; +  } + +  bool AddSymbolsForStack(CommandReturnObject &result, bool &flush) { +    assert(m_current_stack_option.GetOptionValue().OptionWasSet()); + +    Process *process = m_exe_ctx.GetProcessPtr(); +    if (!process) { +      result.AppendError( +          "a process must exist in order to use the --stack option"); +      return false; +    } + +    const StateType process_state = process->GetState(); +    if (!StateIsStoppedState(process_state, true)) { +      result.AppendErrorWithFormat("process is not stopped: %s", +                                   StateAsCString(process_state)); +      return false; +    } + +    Thread *thread = m_exe_ctx.GetThreadPtr(); +    if (!thread) { +      result.AppendError("invalid current thread"); +      return false; +    } + +    bool symbols_found = false; +    uint32_t frame_count = thread->GetStackFrameCount(); +    for (uint32_t i = 0; i < frame_count; ++i) { +      lldb::StackFrameSP frame_sp = thread->GetStackFrameAtIndex(i); + +      ModuleSP frame_module_sp( +          frame_sp->GetSymbolContext(eSymbolContextModule).module_sp); +      if (!frame_module_sp) +        continue; + +      ModuleSpec module_spec; +      module_spec.GetUUID() = frame_module_sp->GetUUID(); + +      if (FileSystem::Instance().Exists( +              frame_module_sp->GetPlatformFileSpec())) { +        module_spec.GetArchitecture() = frame_module_sp->GetArchitecture(); +        module_spec.GetFileSpec() = frame_module_sp->GetPlatformFileSpec(); +      } + +      bool current_frame_flush = false; +      if (DownloadObjectAndSymbolFile(module_spec, result, current_frame_flush)) +        symbols_found = true; +      flush |= current_frame_flush; +    } + +    if (!symbols_found) { +      result.AppendError( +          "unable to find debug symbols in the current call stack"); +      return false; +    } + +    return true; +  } +    bool DoExecute(Args &args, CommandReturnObject &result) override {      Target *target = m_exe_ctx.GetTargetPtr();      result.SetStatus(eReturnStatusFailed); @@ -4150,100 +4320,22 @@ protected:      const bool file_option_set = m_file_option.GetOptionValue().OptionWasSet();      const bool frame_option_set =          m_current_frame_option.GetOptionValue().OptionWasSet(); +    const bool stack_option_set = +        m_current_stack_option.GetOptionValue().OptionWasSet();      const size_t argc = args.GetArgumentCount();      if (argc == 0) { -      if (uuid_option_set || file_option_set || frame_option_set) { -        bool success = false; -        bool error_set = false; -        if (frame_option_set) { -          Process *process = m_exe_ctx.GetProcessPtr(); -          if (process) { -            const StateType process_state = process->GetState(); -            if (StateIsStoppedState(process_state, true)) { -              StackFrame *frame = m_exe_ctx.GetFramePtr(); -              if (frame) { -                ModuleSP frame_module_sp( -                    frame->GetSymbolContext(eSymbolContextModule).module_sp); -                if (frame_module_sp) { -                  if (FileSystem::Instance().Exists( -                          frame_module_sp->GetPlatformFileSpec())) { -                    module_spec.GetArchitecture() = -                        frame_module_sp->GetArchitecture(); -                    module_spec.GetFileSpec() = -                        frame_module_sp->GetPlatformFileSpec(); -                  } -                  module_spec.GetUUID() = frame_module_sp->GetUUID(); -                  success = module_spec.GetUUID().IsValid() || -                            module_spec.GetFileSpec(); -                } else { -                  result.AppendError("frame has no module"); -                  error_set = true; -                } -              } else { -                result.AppendError("invalid current frame"); -                error_set = true; -              } -            } else { -              result.AppendErrorWithFormat("process is not stopped: %s", -                                           StateAsCString(process_state)); -              error_set = true; -            } -          } else { -            result.AppendError( -                "a process must exist in order to use the --frame option"); -            error_set = true; -          } -        } else { -          if (uuid_option_set) { -            module_spec.GetUUID() = -                m_uuid_option_group.GetOptionValue().GetCurrentValue(); -            success |= module_spec.GetUUID().IsValid(); -          } else if (file_option_set) { -            module_spec.GetFileSpec() = -                m_file_option.GetOptionValue().GetCurrentValue(); -            ModuleSP module_sp( -                target->GetImages().FindFirstModule(module_spec)); -            if (module_sp) { -              module_spec.GetFileSpec() = module_sp->GetFileSpec(); -              module_spec.GetPlatformFileSpec() = -                  module_sp->GetPlatformFileSpec(); -              module_spec.GetUUID() = module_sp->GetUUID(); -              module_spec.GetArchitecture() = module_sp->GetArchitecture(); -            } else { -              module_spec.GetArchitecture() = target->GetArchitecture(); -            } -            success |= module_spec.GetUUID().IsValid() || -                       FileSystem::Instance().Exists(module_spec.GetFileSpec()); -          } -        } - -        if (success) { -          if (Symbols::DownloadObjectAndSymbolFile(module_spec)) { -            if (module_spec.GetSymbolFileSpec()) -              success = AddModuleSymbols(target, module_spec, flush, result); -          } -        } - -        if (!success && !error_set) { -          StreamString error_strm; -          if (uuid_option_set) { -            error_strm.PutCString("unable to find debug symbols for UUID "); -            module_spec.GetUUID().Dump(&error_strm); -          } else if (file_option_set) { -            error_strm.PutCString( -                "unable to find debug symbols for the executable file "); -            error_strm << module_spec.GetFileSpec(); -          } else if (frame_option_set) { -            error_strm.PutCString( -                "unable to find debug symbols for the current frame"); -          } -          result.AppendError(error_strm.GetString()); -        } -      } else { +      if (uuid_option_set) +        AddSymbolsForUUID(result, flush); +      else if (file_option_set) +        AddSymbolsForFile(result, flush); +      else if (frame_option_set) +        AddSymbolsForFrame(result, flush); +      else if (stack_option_set) +        AddSymbolsForStack(result, flush); +      else          result.AppendError("one or more symbol file paths must be specified, "                             "or options must be specified"); -      }      } else {        if (uuid_option_set) {          result.AppendError("specify either one or more paths to symbol files " @@ -4310,6 +4402,7 @@ protected:    OptionGroupUUID m_uuid_option_group;    OptionGroupFile m_file_option;    OptionGroupBoolean m_current_frame_option; +  OptionGroupBoolean m_current_stack_option;  };  #pragma mark CommandObjectTargetSymbols @@ -4511,29 +4604,29 @@ public:  Command Based stop-hooks:  -------------------------    Stop hooks can run a list of lldb commands by providing one or more -  --one-line-command options.  The commands will get run in the order they are  +  --one-line-command options.  The commands will get run in the order they are    added.  Or you can provide no commands, in which case you will enter a    command editor where you can enter the commands to be run. -   +  Python Based Stop Hooks:  ------------------------    Stop hooks can be implemented with a suitably defined Python class, whose name    is passed in the --python-class option. -   +    When the stop hook is added, the class is initialized by calling: -   +      def __init__(self, target, extra_args, internal_dict): -     +      target: The target that the stop hook is being added to. -    extra_args: An SBStructuredData Dictionary filled with the -key -value  -                option pairs passed to the command.      +    extra_args: An SBStructuredData Dictionary filled with the -key -value +                option pairs passed to the command.      dict: An implementation detail provided by lldb. -  Then when the stop-hook triggers, lldb will run the 'handle_stop' method.  +  Then when the stop-hook triggers, lldb will run the 'handle_stop' method.    The method has the signature: -   +      def handle_stop(self, exe_ctx, stream): -     +      exe_ctx: An SBExecutionContext for the thread that has stopped.      stream: An SBStream, anything written to this stream will be printed in the              the stop message when the process stops. @@ -4542,12 +4635,12 @@ Python Based Stop Hooks:                    from all the stop hook executions on threads that stopped                    with a reason, then the process will continue.  Note that this                    will happen only after all the stop hooks are run. -     +  Filter Options:  ---------------    Stop hooks can be set to always run, or to only run when the stopped thread    matches the filter options passed on the command line.  The available filter -  options include a shared library or a thread or queue specification,  +  options include a shared library or a thread or queue specification,    a line range in a source file, a function name or a class name.              )");      m_all_options.Append(&m_python_class_options, @@ -4896,6 +4989,55 @@ public:    ~CommandObjectMultiwordTargetStopHooks() override = default;  }; +#pragma mark CommandObjectTargetDumpTypesystem + +/// Dumps the TypeSystem of the selected Target. +class CommandObjectTargetDumpTypesystem : public CommandObjectParsed { +public: +  CommandObjectTargetDumpTypesystem(CommandInterpreter &interpreter) +      : CommandObjectParsed( +            interpreter, "target dump typesystem", +            "Dump the state of the target's internal type system.\n" +            "Intended to be used for debugging LLDB itself.", +            nullptr, eCommandRequiresTarget) {} + +  ~CommandObjectTargetDumpTypesystem() override = default; + +protected: +  bool DoExecute(Args &command, CommandReturnObject &result) override { +    if (!command.empty()) { +      result.AppendError("target dump typesystem doesn't take arguments."); +      return result.Succeeded(); +    } + +    // Go over every scratch TypeSystem and dump to the command output. +    for (TypeSystem *ts : GetSelectedTarget().GetScratchTypeSystems()) +      ts->Dump(result.GetOutputStream().AsRawOstream()); + +    result.SetStatus(eReturnStatusSuccessFinishResult); +    return result.Succeeded(); +  } +}; + +#pragma mark CommandObjectTargetDump + +/// Multi-word command for 'target dump'. +class CommandObjectTargetDump : public CommandObjectMultiword { +public: +  // Constructors and Destructors +  CommandObjectTargetDump(CommandInterpreter &interpreter) +      : CommandObjectMultiword( +            interpreter, "target dump", +            "Commands for dumping information about the target.", +            "target dump [typesystem]") { +    LoadSubCommand( +        "typesystem", +        CommandObjectSP(new CommandObjectTargetDumpTypesystem(interpreter))); +  } + +  ~CommandObjectTargetDump() override = default; +}; +  #pragma mark CommandObjectMultiwordTarget  // CommandObjectMultiwordTarget @@ -4909,6 +5051,8 @@ CommandObjectMultiwordTarget::CommandObjectMultiwordTarget(                   CommandObjectSP(new CommandObjectTargetCreate(interpreter)));    LoadSubCommand("delete",                   CommandObjectSP(new CommandObjectTargetDelete(interpreter))); +  LoadSubCommand("dump", +                 CommandObjectSP(new CommandObjectTargetDump(interpreter)));    LoadSubCommand("list",                   CommandObjectSP(new CommandObjectTargetList(interpreter)));    LoadSubCommand("select", | 
