[Lldb-commits] [lldb] [lldb] Unify the way we get the Target in CommandObject (PR #101208)

Jonas Devlieghere via lldb-commits lldb-commits at lists.llvm.org
Tue Jul 30 10:30:41 PDT 2024


https://github.com/JDevlieghere created https://github.com/llvm/llvm-project/pull/101208

Currently, CommandObjects are obtaining a target in a variety of ways. Often the command incorrectly operates on the selected target. As an example, when a breakpoint command is running, the current target is passed into the command but the target that hit the breakpoint is not the selected target. In other places we use the CommandObject's execution context, which is frozen during the execution of the command, which comes with its own limitations. And of course there's all the places where we need to use, or to fallback on the dummy target

Instead of having to guess how to get the target, this patch introduces one helper function in CommandObject to get the most relevant target. In order of priority, that's the target from the command object's execution context, from the interpreter's execution context, the selected target or the dummy target. This function always return the dummy target if explicitly requested.

rdar://110846511

>From 515525357026eb49508b1322b3b9ee40840f7b5e Mon Sep 17 00:00:00 2001
From: Jonas Devlieghere <jonas at devlieghere.com>
Date: Mon, 29 Jul 2024 16:32:45 -0700
Subject: [PATCH] [lldb] Unify the way we get the Target in CommandObject

Currently, CommandObjects are obtaining a target in a variety of ways.
Often the command incorrectly operates on the selected target. As an
example, when a breakpoint command is running, the current target is
passed into the command but the target that hit the breakpoint is not
the selected target. In other places we use the CommandObject's
execution context, which is frozen during the execution of the command,
which comes with its own limitations. And of course there's all the
places where we need to use, or to fallback on the dummy target

Instead of having to guess how to get the target, this patch introduces
one helper function in CommandObject to get the most relevant target. In
order of priority, that's the target from the command object's execution
context, from the interpreter's execution context, the selected target
or the dummy target. This function always return the dummy target if
explicitly requested.

rdar://110846511
---
 lldb/include/lldb/Interpreter/CommandObject.h | 12 ++---
 .../Commands/CommandObjectBreakpoint.cpp      | 31 ++++++------
 .../CommandObjectBreakpointCommand.cpp        |  6 +--
 .../Commands/CommandObjectDWIMPrint.cpp       |  2 +-
 .../Commands/CommandObjectDisassemble.cpp     | 10 ++--
 .../Commands/CommandObjectExpression.cpp      |  8 +--
 lldb/source/Commands/CommandObjectFrame.cpp   | 28 ++++-------
 lldb/source/Commands/CommandObjectProcess.cpp |  4 +-
 lldb/source/Commands/CommandObjectTarget.cpp  | 50 +++++++++----------
 lldb/source/Commands/CommandObjectThread.cpp  |  2 +-
 .../Commands/CommandObjectWatchpoint.cpp      | 16 +++---
 .../CommandObjectWatchpointCommand.cpp        |  6 +--
 lldb/source/Interpreter/CommandObject.cpp     | 34 +++++++------
 .../DarwinLog/StructuredDataDarwinLog.cpp     |  4 +-
 14 files changed, 105 insertions(+), 108 deletions(-)

diff --git a/lldb/include/lldb/Interpreter/CommandObject.h b/lldb/include/lldb/Interpreter/CommandObject.h
index d48dbcdd5a5da..16d89f1e5db87 100644
--- a/lldb/include/lldb/Interpreter/CommandObject.h
+++ b/lldb/include/lldb/Interpreter/CommandObject.h
@@ -369,12 +369,12 @@ class CommandObject : public std::enable_shared_from_this<CommandObject> {
            "currently stopped.";
   }
 
-  // This is for use in the command interpreter, when you either want the
-  // selected target, or if no target is present you want to prime the dummy
-  // target with entities that will be copied over to new targets.
-  Target &GetSelectedOrDummyTarget(bool prefer_dummy = false);
-  Target &GetSelectedTarget();
-  Target &GetDummyTarget();
+  // This is for use in the command interpreter and returns the most relevant
+  // target. In order of priority, that's the target from the command object's
+  // execution context, from the interpreter's execution context, the selected
+  // target or the dummy target. This function always return the dummy target if
+  // explicitly requested.
+  Target &GetTarget(bool dummy = false);
 
   // If a command needs to use the "current" thread, use this call. Command
   // objects will have an ExecutionContext to use, and that may or may not have
diff --git a/lldb/source/Commands/CommandObjectBreakpoint.cpp b/lldb/source/Commands/CommandObjectBreakpoint.cpp
index 773f8ed2fa8af..40be0cf02cd35 100644
--- a/lldb/source/Commands/CommandObjectBreakpoint.cpp
+++ b/lldb/source/Commands/CommandObjectBreakpoint.cpp
@@ -539,7 +539,7 @@ class CommandObjectBreakpointSet : public CommandObjectParsed {
 
 protected:
   void DoExecute(Args &command, CommandReturnObject &result) override {
-    Target &target = GetSelectedOrDummyTarget(m_dummy_options.m_use_dummy);
+    Target &target = GetTarget(m_dummy_options.m_use_dummy);
 
     // The following are the various types of breakpoints that could be set:
     //   1).  -f -l -p  [-s -g]   (setting breakpoint by source location)
@@ -747,7 +747,7 @@ class CommandObjectBreakpointSet : public CommandObjectParsed {
       const bool show_locations = false;
       bp_sp->GetDescription(&output_stream, lldb::eDescriptionLevelInitial,
                             show_locations);
-      if (&target == &GetDummyTarget())
+      if (&target == &GetTarget(/*dummy=*/true))
         output_stream.Printf("Breakpoint set in dummy target, will get copied "
                              "into future targets.\n");
       else {
@@ -839,7 +839,7 @@ class CommandObjectBreakpointModify : public CommandObjectParsed {
 
 protected:
   void DoExecute(Args &command, CommandReturnObject &result) override {
-    Target &target = GetSelectedOrDummyTarget(m_dummy_opts.m_use_dummy);
+    Target &target = GetTarget(m_dummy_opts.m_use_dummy);
 
     std::unique_lock<std::recursive_mutex> lock;
     target.GetBreakpointList().GetListMutex(lock);
@@ -903,7 +903,7 @@ class CommandObjectBreakpointEnable : public CommandObjectParsed {
 
 protected:
   void DoExecute(Args &command, CommandReturnObject &result) override {
-    Target &target = GetSelectedOrDummyTarget();
+    Target &target = GetTarget();
 
     std::unique_lock<std::recursive_mutex> lock;
     target.GetBreakpointList().GetListMutex(lock);
@@ -1010,7 +1010,7 @@ the second re-enables the first location.");
 
 protected:
   void DoExecute(Args &command, CommandReturnObject &result) override {
-    Target &target = GetSelectedOrDummyTarget();
+    Target &target = GetTarget();
     std::unique_lock<std::recursive_mutex> lock;
     target.GetBreakpointList().GetListMutex(lock);
 
@@ -1148,7 +1148,7 @@ class CommandObjectBreakpointList : public CommandObjectParsed {
 
 protected:
   void DoExecute(Args &command, CommandReturnObject &result) override {
-    Target &target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
+    Target &target = GetTarget(m_options.m_use_dummy);
 
     const BreakpointList &breakpoints =
         target.GetBreakpointList(m_options.m_internal);
@@ -1267,7 +1267,7 @@ class CommandObjectBreakpointClear : public CommandObjectParsed {
 
 protected:
   void DoExecute(Args &command, CommandReturnObject &result) override {
-    Target &target = GetSelectedOrDummyTarget();
+    Target &target = GetTarget();
 
     // The following are the various types of breakpoints that could be
     // cleared:
@@ -1416,7 +1416,7 @@ class CommandObjectBreakpointDelete : public CommandObjectParsed {
 
 protected:
   void DoExecute(Args &command, CommandReturnObject &result) override {
-    Target &target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
+    Target &target = GetTarget(m_options.m_use_dummy);
     result.Clear();
     
     std::unique_lock<std::recursive_mutex> lock;
@@ -1676,7 +1676,7 @@ class CommandObjectBreakpointNameConfigure : public CommandObjectParsed {
       return;
     }
 
-    Target &target = GetSelectedOrDummyTarget(false);
+    Target &target = GetTarget(false);
 
     std::unique_lock<std::recursive_mutex> lock;
     target.GetBreakpointList().GetListMutex(lock);
@@ -1763,8 +1763,7 @@ class CommandObjectBreakpointNameAdd : public CommandObjectParsed {
       return;
     }
 
-    Target &target =
-        GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
+    Target &target = GetTarget(m_name_options.m_use_dummy.GetCurrentValue());
 
     std::unique_lock<std::recursive_mutex> lock;
     target.GetBreakpointList().GetListMutex(lock);
@@ -1837,8 +1836,7 @@ class CommandObjectBreakpointNameDelete : public CommandObjectParsed {
       return;
     }
 
-    Target &target =
-        GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
+    Target &target = GetTarget(m_name_options.m_use_dummy.GetCurrentValue());
 
     std::unique_lock<std::recursive_mutex> lock;
     target.GetBreakpointList().GetListMutex(lock);
@@ -1896,8 +1894,7 @@ class CommandObjectBreakpointNameList : public CommandObjectParsed {
 
 protected:
   void DoExecute(Args &command, CommandReturnObject &result) override {
-    Target &target =
-        GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
+    Target &target = GetTarget(m_name_options.m_use_dummy.GetCurrentValue());
 
     std::vector<std::string> name_list;
     if (command.empty()) {
@@ -2209,7 +2206,7 @@ class CommandObjectBreakpointRead : public CommandObjectParsed {
 
 protected:
   void DoExecute(Args &command, CommandReturnObject &result) override {
-    Target &target = GetSelectedOrDummyTarget();
+    Target &target = GetTarget();
 
     std::unique_lock<std::recursive_mutex> lock;
     target.GetBreakpointList().GetListMutex(lock);
@@ -2319,7 +2316,7 @@ class CommandObjectBreakpointWrite : public CommandObjectParsed {
 
 protected:
   void DoExecute(Args &command, CommandReturnObject &result) override {
-    Target &target = GetSelectedOrDummyTarget();
+    Target &target = GetTarget();
 
     std::unique_lock<std::recursive_mutex> lock;
     target.GetBreakpointList().GetListMutex(lock);
diff --git a/lldb/source/Commands/CommandObjectBreakpointCommand.cpp b/lldb/source/Commands/CommandObjectBreakpointCommand.cpp
index 6ebe6e8a35570..fb352e70c2355 100644
--- a/lldb/source/Commands/CommandObjectBreakpointCommand.cpp
+++ b/lldb/source/Commands/CommandObjectBreakpointCommand.cpp
@@ -323,7 +323,7 @@ are no syntax errors may indicate that a function was declared but never called.
 
 protected:
   void DoExecute(Args &command, CommandReturnObject &result) override {
-    Target &target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
+    Target &target = GetTarget(m_options.m_use_dummy);
 
     const BreakpointList &breakpoints = target.GetBreakpointList();
     size_t num_breakpoints = breakpoints.GetSize();
@@ -481,7 +481,7 @@ class CommandObjectBreakpointCommandDelete : public CommandObjectParsed {
 
 protected:
   void DoExecute(Args &command, CommandReturnObject &result) override {
-    Target &target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
+    Target &target = GetTarget(m_options.m_use_dummy);
 
     const BreakpointList &breakpoints = target.GetBreakpointList();
     size_t num_breakpoints = breakpoints.GetSize();
@@ -548,7 +548,7 @@ class CommandObjectBreakpointCommandList : public CommandObjectParsed {
 
 protected:
   void DoExecute(Args &command, CommandReturnObject &result) override {
-    Target *target = &GetSelectedTarget();
+    Target *target = &GetTarget();
 
     const BreakpointList &breakpoints = target->GetBreakpointList();
     size_t num_breakpoints = breakpoints.GetSize();
diff --git a/lldb/source/Commands/CommandObjectDWIMPrint.cpp b/lldb/source/Commands/CommandObjectDWIMPrint.cpp
index b7cd955e00203..35db422121a20 100644
--- a/lldb/source/Commands/CommandObjectDWIMPrint.cpp
+++ b/lldb/source/Commands/CommandObjectDWIMPrint.cpp
@@ -77,7 +77,7 @@ void CommandObjectDWIMPrint::DoExecute(StringRef command,
 
   Target *target_ptr = m_exe_ctx.GetTargetPtr();
   // Fallback to the dummy target, which can allow for expression evaluation.
-  Target &target = target_ptr ? *target_ptr : GetDummyTarget();
+  Target &target = target_ptr ? *target_ptr : GetTarget(/*dummy=*/true);
 
   EvaluateExpressionOptions eval_options =
       m_expr_options.GetEvaluateExpressionOptions(target, m_varobj_options);
diff --git a/lldb/source/Commands/CommandObjectDisassemble.cpp b/lldb/source/Commands/CommandObjectDisassemble.cpp
index d975e39801317..8ec55cc120725 100644
--- a/lldb/source/Commands/CommandObjectDisassemble.cpp
+++ b/lldb/source/Commands/CommandObjectDisassemble.cpp
@@ -227,7 +227,7 @@ llvm::Error CommandObjectDisassemble::CheckRangeSize(const AddressRange &range,
     return llvm::Error::success();
   StreamString msg;
   msg << "Not disassembling " << what << " because it is very large ";
-  range.Dump(&msg, &GetSelectedTarget(), Address::DumpStyleLoadAddress,
+  range.Dump(&msg, &GetTarget(), Address::DumpStyleLoadAddress,
              Address::DumpStyleFileAddress);
   msg << ". To disassemble specify an instruction count limit, start/stop "
          "addresses or use the --force option.";
@@ -252,7 +252,7 @@ CommandObjectDisassemble::GetContainingAddressRanges() {
     }
   };
 
-  Target &target = GetSelectedTarget();
+  Target &target = GetTarget();
   if (!target.GetSectionLoadList().IsEmpty()) {
     Address symbol_containing_address;
     if (target.GetSectionLoadList().ResolveLoadAddress(
@@ -351,8 +351,8 @@ CommandObjectDisassemble::GetNameRanges(CommandReturnObject &result) {
 
   // Find functions matching the given name.
   SymbolContextList sc_list;
-  GetSelectedTarget().GetImages().FindFunctions(name, eFunctionNameTypeAuto,
-                                                function_options, sc_list);
+  GetTarget().GetImages().FindFunctions(name, eFunctionNameTypeAuto,
+                                        function_options, sc_list);
 
   std::vector<AddressRange> ranges;
   llvm::Error range_errs = llvm::Error::success();
@@ -439,7 +439,7 @@ CommandObjectDisassemble::GetRangesForSelectedMode(
 
 void CommandObjectDisassemble::DoExecute(Args &command,
                                          CommandReturnObject &result) {
-  Target *target = &GetSelectedTarget();
+  Target *target = &GetTarget();
 
   if (!m_options.arch.IsValid())
     m_options.arch = target->GetArchitecture();
diff --git a/lldb/source/Commands/CommandObjectExpression.cpp b/lldb/source/Commands/CommandObjectExpression.cpp
index eb76753d98efc..a91e6a08d9933 100644
--- a/lldb/source/Commands/CommandObjectExpression.cpp
+++ b/lldb/source/Commands/CommandObjectExpression.cpp
@@ -344,7 +344,7 @@ void CommandObjectExpression::HandleCompletion(CompletionRequest &request) {
     return;
 
   Target *exe_target = exe_ctx.GetTargetPtr();
-  Target &target = exe_target ? *exe_target : GetDummyTarget();
+  Target &target = exe_target ? *exe_target : GetTarget(/*dummy=*/true);
 
   unsigned cursor_pos = request.GetRawCursorPos();
   // Get the full user input including the suffix. The suffix is necessary
@@ -407,7 +407,7 @@ bool CommandObjectExpression::EvaluateExpression(llvm::StringRef expr,
   // that use an input reader...
   ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
   Target *exe_target = exe_ctx.GetTargetPtr();
-  Target &target = exe_target ? *exe_target : GetDummyTarget();
+  Target &target = exe_target ? *exe_target : GetTarget(/*dummy=*/true);
 
   lldb::ValueObjectSP result_valobj_sp;
   StackFrame *frame = exe_ctx.GetFramePtr();
@@ -605,7 +605,7 @@ void CommandObjectExpression::DoExecute(llvm::StringRef command,
       return;
 
     if (m_repl_option.GetOptionValue().GetCurrentValue()) {
-      Target &target = GetSelectedOrDummyTarget();
+      Target &target = GetTarget();
       // Drop into REPL
       m_expr_lines.clear();
       m_expr_line_count = 0;
@@ -665,7 +665,7 @@ void CommandObjectExpression::DoExecute(llvm::StringRef command,
     }
   }
 
-  Target &target = GetSelectedOrDummyTarget();
+  Target &target = GetTarget();
   if (EvaluateExpression(expr, result.GetOutputStream(),
                          result.GetErrorStream(), result)) {
 
diff --git a/lldb/source/Commands/CommandObjectFrame.cpp b/lldb/source/Commands/CommandObjectFrame.cpp
index 3f4178c1a9595..29e460fe3885f 100644
--- a/lldb/source/Commands/CommandObjectFrame.cpp
+++ b/lldb/source/Commands/CommandObjectFrame.cpp
@@ -687,7 +687,7 @@ may even involve JITing and running code in the target program.)");
                                            m_cmd_name);
 
     // Increment statistics.
-    TargetStats &target_stats = GetSelectedOrDummyTarget().GetStatistics();
+    TargetStats &target_stats = GetTarget().GetStatistics();
     if (result.Succeeded())
       target_stats.GetFrameVariableStats().NotifySuccess();
     else
@@ -874,13 +874,13 @@ void CommandObjectFrameRecognizerAdd::DoExecute(Args &command,
         RegularExpressionSP(new RegularExpression(m_options.m_module));
     auto func =
         RegularExpressionSP(new RegularExpression(m_options.m_symbols.front()));
-    GetSelectedOrDummyTarget().GetFrameRecognizerManager().AddRecognizer(
+    GetTarget().GetFrameRecognizerManager().AddRecognizer(
         recognizer_sp, module, func, m_options.m_first_instruction_only);
   } else {
     auto module = ConstString(m_options.m_module);
     std::vector<ConstString> symbols(m_options.m_symbols.begin(),
                                      m_options.m_symbols.end());
-    GetSelectedOrDummyTarget().GetFrameRecognizerManager().AddRecognizer(
+    GetTarget().GetFrameRecognizerManager().AddRecognizer(
         recognizer_sp, module, symbols, m_options.m_first_instruction_only);
   }
 #endif
@@ -898,9 +898,7 @@ class CommandObjectFrameRecognizerClear : public CommandObjectParsed {
 
 protected:
   void DoExecute(Args &command, CommandReturnObject &result) override {
-    GetSelectedOrDummyTarget()
-        .GetFrameRecognizerManager()
-        .RemoveAllRecognizers();
+    GetTarget().GetFrameRecognizerManager().RemoveAllRecognizers();
     result.SetStatus(eReturnStatusSuccessFinishResult);
   }
 };
@@ -922,7 +920,7 @@ class CommandObjectFrameRecognizerDelete : public CommandObjectParsed {
     if (request.GetCursorIndex() != 0)
       return;
 
-    GetSelectedOrDummyTarget().GetFrameRecognizerManager().ForEach(
+    GetTarget().GetFrameRecognizerManager().ForEach(
         [&request](uint32_t rid, std::string rname, std::string module,
                    llvm::ArrayRef<lldb_private::ConstString> symbols,
                    bool regexp) {
@@ -953,9 +951,7 @@ class CommandObjectFrameRecognizerDelete : public CommandObjectParsed {
         return;
       }
 
-      GetSelectedOrDummyTarget()
-          .GetFrameRecognizerManager()
-          .RemoveAllRecognizers();
+      GetTarget().GetFrameRecognizerManager().RemoveAllRecognizers();
       result.SetStatus(eReturnStatusSuccessFinishResult);
       return;
     }
@@ -973,9 +969,8 @@ class CommandObjectFrameRecognizerDelete : public CommandObjectParsed {
       return;
     }
 
-    if (!GetSelectedOrDummyTarget()
-             .GetFrameRecognizerManager()
-             .RemoveRecognizerWithID(recognizer_id)) {
+    if (!GetTarget().GetFrameRecognizerManager().RemoveRecognizerWithID(
+            recognizer_id)) {
       result.AppendErrorWithFormat("'%s' is not a valid recognizer id.\n",
                                    command.GetArgumentAtIndex(0));
       return;
@@ -996,7 +991,7 @@ class CommandObjectFrameRecognizerList : public CommandObjectParsed {
 protected:
   void DoExecute(Args &command, CommandReturnObject &result) override {
     bool any_printed = false;
-    GetSelectedOrDummyTarget().GetFrameRecognizerManager().ForEach(
+    GetTarget().GetFrameRecognizerManager().ForEach(
         [&result, &any_printed](
             uint32_t recognizer_id, std::string name, std::string module,
             llvm::ArrayRef<ConstString> symbols, bool regexp) {
@@ -1073,9 +1068,8 @@ class CommandObjectFrameRecognizerInfo : public CommandObjectParsed {
       return;
     }
 
-    auto recognizer = GetSelectedOrDummyTarget()
-                          .GetFrameRecognizerManager()
-                          .GetRecognizerForFrame(frame_sp);
+    auto recognizer =
+        GetTarget().GetFrameRecognizerManager().GetRecognizerForFrame(frame_sp);
 
     Stream &output_stream = result.GetOutputStream();
     output_stream.Printf("frame %d ", frame_index);
diff --git a/lldb/source/Commands/CommandObjectProcess.cpp b/lldb/source/Commands/CommandObjectProcess.cpp
index e605abdb3c771..fe5c5041af2d1 100644
--- a/lldb/source/Commands/CommandObjectProcess.cpp
+++ b/lldb/source/Commands/CommandObjectProcess.cpp
@@ -1584,7 +1584,7 @@ class CommandObjectProcessHandle : public CommandObjectParsed {
 
 protected:
   void DoExecute(Args &signal_args, CommandReturnObject &result) override {
-    Target &target = GetSelectedOrDummyTarget();
+    Target &target = GetTarget();
 
     // Any signals that are being set should be added to the Target's
     // DummySignals so they will get applied on rerun, etc.
@@ -1662,7 +1662,7 @@ class CommandObjectProcessHandle : public CommandObjectParsed {
     if (m_options.do_clear) {
       target.ClearDummySignals(signal_args);
       if (m_options.dummy)
-        GetDummyTarget().ClearDummySignals(signal_args);
+        GetTarget(/*dummy=*/true).ClearDummySignals(signal_args);
       result.SetStatus(eReturnStatusSuccessFinishNoResult);
       return;
     }
diff --git a/lldb/source/Commands/CommandObjectTarget.cpp b/lldb/source/Commands/CommandObjectTarget.cpp
index cc381a2ecee1d..3e077f00e59d2 100644
--- a/lldb/source/Commands/CommandObjectTarget.cpp
+++ b/lldb/source/Commands/CommandObjectTarget.cpp
@@ -1027,7 +1027,7 @@ class CommandObjectTargetModulesSearchPathsAdd : public CommandObjectParsed {
 
 protected:
   void DoExecute(Args &command, CommandReturnObject &result) override {
-    Target *target = &GetSelectedTarget();
+    Target *target = &GetTarget();
     const size_t argc = command.GetArgumentCount();
     if (argc & 1) {
       result.AppendError("add requires an even number of arguments\n");
@@ -1074,7 +1074,7 @@ class CommandObjectTargetModulesSearchPathsClear : public CommandObjectParsed {
 
 protected:
   void DoExecute(Args &command, CommandReturnObject &result) override {
-    Target *target = &GetSelectedTarget();
+    Target *target = &GetTarget();
     bool notify = true;
     target->GetImageSearchPathList().Clear(notify);
     result.SetStatus(eReturnStatusSuccessFinishNoResult);
@@ -1148,7 +1148,7 @@ class CommandObjectTargetModulesSearchPathsInsert : public CommandObjectParsed {
 
 protected:
   void DoExecute(Args &command, CommandReturnObject &result) override {
-    Target *target = &GetSelectedTarget();
+    Target *target = &GetTarget();
     size_t argc = command.GetArgumentCount();
     // check for at least 3 arguments and an odd number of parameters
     if (argc >= 3 && argc & 1) {
@@ -1203,7 +1203,7 @@ class CommandObjectTargetModulesSearchPathsList : public CommandObjectParsed {
 
 protected:
   void DoExecute(Args &command, CommandReturnObject &result) override {
-    Target *target = &GetSelectedTarget();
+    Target *target = &GetTarget();
 
     target->GetImageSearchPathList().Dump(&result.GetOutputStream());
     result.SetStatus(eReturnStatusSuccessFinishResult);
@@ -1226,7 +1226,7 @@ class CommandObjectTargetModulesSearchPathsQuery : public CommandObjectParsed {
 
 protected:
   void DoExecute(Args &command, CommandReturnObject &result) override {
-    Target *target = &GetSelectedTarget();
+    Target *target = &GetTarget();
     if (command.GetArgumentCount() != 1) {
       result.AppendError("query requires one argument\n");
       return;
@@ -1898,7 +1898,7 @@ class CommandObjectTargetModulesDumpObjfile
 
 protected:
   void DoExecute(Args &command, CommandReturnObject &result) override {
-    Target *target = &GetSelectedTarget();
+    Target *target = &GetTarget();
 
     uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
     result.GetOutputStream().SetAddressByteSize(addr_byte_size);
@@ -1999,7 +1999,7 @@ class CommandObjectTargetModulesDumpSymtab
 
 protected:
   void DoExecute(Args &command, CommandReturnObject &result) override {
-    Target *target = &GetSelectedTarget();
+    Target *target = &GetTarget();
     uint32_t num_dumped = 0;
     Mangled::NamePreference name_preference =
         (m_options.m_prefer_mangled ? Mangled::ePreferMangled
@@ -2097,7 +2097,7 @@ class CommandObjectTargetModulesDumpSections
 
 protected:
   void DoExecute(Args &command, CommandReturnObject &result) override {
-    Target *target = &GetSelectedTarget();
+    Target *target = &GetTarget();
     uint32_t num_dumped = 0;
 
     uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
@@ -2238,7 +2238,7 @@ class CommandObjectTargetModulesDumpClangAST
 
 protected:
   void DoExecute(Args &command, CommandReturnObject &result) override {
-    Target *target = &GetSelectedTarget();
+    Target *target = &GetTarget();
 
     const ModuleList &module_list = target->GetImages();
     const size_t num_modules = module_list.GetSize();
@@ -2309,7 +2309,7 @@ class CommandObjectTargetModulesDumpSymfile
 
 protected:
   void DoExecute(Args &command, CommandReturnObject &result) override {
-    Target *target = &GetSelectedTarget();
+    Target *target = &GetTarget();
     uint32_t num_dumped = 0;
 
     uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
@@ -2533,7 +2533,7 @@ class CommandObjectTargetModulesDumpSeparateDebugInfoFiles
 
 protected:
   void DoExecute(Args &command, CommandReturnObject &result) override {
-    Target &target = GetSelectedTarget();
+    Target &target = GetTarget();
     uint32_t num_dumped = 0;
 
     uint32_t addr_byte_size = target.GetArchitecture().GetAddressByteSize();
@@ -2726,7 +2726,7 @@ class CommandObjectTargetModulesAdd : public CommandObjectParsed {
   OptionGroupFile m_symbol_file;
 
   void DoExecute(Args &args, CommandReturnObject &result) override {
-    Target *target = &GetSelectedTarget();
+    Target *target = &GetTarget();
     bool flush = false;
 
     const size_t argc = args.GetArgumentCount();
@@ -2876,7 +2876,7 @@ class CommandObjectTargetModulesLoad
 
 protected:
   void DoExecute(Args &args, CommandReturnObject &result) override {
-    Target *target = &GetSelectedTarget();
+    Target *target = &GetTarget();
     const bool load = m_load_option.GetOptionValue().GetCurrentValue();
     const bool set_pc = m_pc_option.GetOptionValue().GetCurrentValue();
 
@@ -3166,7 +3166,7 @@ class CommandObjectTargetModulesList : public CommandObjectParsed {
 
 protected:
   void DoExecute(Args &command, CommandReturnObject &result) override {
-    Target *target = GetDebugger().GetSelectedTarget().get();
+    Target *target = &GetTarget();
     const bool use_global_module_list = m_options.m_use_global_module_list;
     // Define a local module list here to ensure it lives longer than any
     // "locker" object which might lock its contents below (through the
@@ -3969,7 +3969,7 @@ class CommandObjectTargetModulesLookup : public CommandObjectParsed {
       return false;
     case eLookupTypeType:
       if (!m_options.m_str.empty()) {
-        if (LookupTypeHere(&GetSelectedTarget(), m_interpreter,
+        if (LookupTypeHere(&GetTarget(), m_interpreter,
                            result.GetOutputStream(), *sym_ctx.module_sp,
                            m_options.m_str.c_str(), m_options.m_use_regex)) {
           result.SetStatus(eReturnStatusSuccessFinishResult);
@@ -4048,8 +4048,8 @@ class CommandObjectTargetModulesLookup : public CommandObjectParsed {
     case eLookupTypeType:
       if (!m_options.m_str.empty()) {
         if (LookupTypeInModule(
-                &GetSelectedTarget(), m_interpreter, result.GetOutputStream(),
-                module, m_options.m_str.c_str(), m_options.m_use_regex)) {
+                &GetTarget(), m_interpreter, result.GetOutputStream(), module,
+                m_options.m_str.c_str(), m_options.m_use_regex)) {
           result.SetStatus(eReturnStatusSuccessFinishResult);
           return true;
         }
@@ -4070,7 +4070,7 @@ class CommandObjectTargetModulesLookup : public CommandObjectParsed {
 
 protected:
   void DoExecute(Args &command, CommandReturnObject &result) override {
-    Target *target = &GetSelectedTarget();
+    Target *target = &GetTarget();
     bool syntax_error = false;
     uint32_t i;
     uint32_t num_successful_lookups = 0;
@@ -4937,7 +4937,7 @@ Filter Options:
                            m_stop_hook_sp->GetID());
           error_sp->Flush();
         }
-        Target *target = GetDebugger().GetSelectedTarget().get();
+        Target *target = &GetTarget();
         if (target) {
           target->UndoCreateStopHook(m_stop_hook_sp->GetID());
         }
@@ -4962,7 +4962,7 @@ Filter Options:
   void DoExecute(Args &command, CommandReturnObject &result) override {
     m_stop_hook_sp.reset();
 
-    Target &target = GetSelectedOrDummyTarget();
+    Target &target = GetTarget();
     Target::StopHookSP new_hook_sp =
         target.CreateStopHook(m_python_class_options.GetName().empty() ?
                                Target::StopHook::StopHookKind::CommandBased
@@ -5099,7 +5099,7 @@ class CommandObjectTargetStopHookDelete : public CommandObjectParsed {
 
 protected:
   void DoExecute(Args &command, CommandReturnObject &result) override {
-    Target &target = GetSelectedOrDummyTarget();
+    Target &target = GetTarget();
     // FIXME: see if we can use the breakpoint id style parser?
     size_t num_args = command.GetArgumentCount();
     if (num_args == 0) {
@@ -5153,7 +5153,7 @@ class CommandObjectTargetStopHookEnableDisable : public CommandObjectParsed {
 
 protected:
   void DoExecute(Args &command, CommandReturnObject &result) override {
-    Target &target = GetSelectedOrDummyTarget();
+    Target &target = GetTarget();
     // FIXME: see if we can use the breakpoint id style parser?
     size_t num_args = command.GetArgumentCount();
     bool success;
@@ -5197,7 +5197,7 @@ class CommandObjectTargetStopHookList : public CommandObjectParsed {
 
 protected:
   void DoExecute(Args &command, CommandReturnObject &result) override {
-    Target &target = GetSelectedOrDummyTarget();
+    Target &target = GetTarget();
 
     size_t num_hooks = target.GetNumStopHooks();
     if (num_hooks == 0) {
@@ -5263,7 +5263,7 @@ class CommandObjectTargetDumpTypesystem : public CommandObjectParsed {
 protected:
   void DoExecute(Args &command, CommandReturnObject &result) override {
     // Go over every scratch TypeSystem and dump to the command output.
-    for (lldb::TypeSystemSP ts : GetSelectedTarget().GetScratchTypeSystems())
+    for (lldb::TypeSystemSP ts : GetTarget().GetScratchTypeSystems())
       if (ts)
         ts->Dump(result.GetOutputStream().AsRawOstream());
 
@@ -5287,7 +5287,7 @@ class CommandObjectTargetDumpSectionLoadList : public CommandObjectParsed {
 
 protected:
   void DoExecute(Args &command, CommandReturnObject &result) override {
-    Target &target = GetSelectedTarget();
+    Target &target = GetTarget();
     target.GetSectionLoadList().Dump(result.GetOutputStream(), &target);
     result.SetStatus(eReturnStatusSuccessFinishResult);
   }
diff --git a/lldb/source/Commands/CommandObjectThread.cpp b/lldb/source/Commands/CommandObjectThread.cpp
index 4398cf3c3b89e..366b6dd965b38 100644
--- a/lldb/source/Commands/CommandObjectThread.cpp
+++ b/lldb/source/Commands/CommandObjectThread.cpp
@@ -882,7 +882,7 @@ class CommandObjectThreadUntil : public CommandObjectParsed {
   void DoExecute(Args &command, CommandReturnObject &result) override {
     bool synchronous_execution = m_interpreter.GetSynchronous();
 
-    Target *target = &GetSelectedTarget();
+    Target *target = &GetTarget();
 
     Process *process = m_exe_ctx.GetProcessPtr();
     if (process == nullptr) {
diff --git a/lldb/source/Commands/CommandObjectWatchpoint.cpp b/lldb/source/Commands/CommandObjectWatchpoint.cpp
index f123211e72377..314c75111a028 100644
--- a/lldb/source/Commands/CommandObjectWatchpoint.cpp
+++ b/lldb/source/Commands/CommandObjectWatchpoint.cpp
@@ -203,7 +203,7 @@ class CommandObjectWatchpointList : public CommandObjectParsed {
 
 protected:
   void DoExecute(Args &command, CommandReturnObject &result) override {
-    Target *target = &GetSelectedTarget();
+    Target *target = &GetTarget();
 
     if (target->GetProcessSP() && target->GetProcessSP()->IsAlive()) {
       std::optional<uint32_t> num_supported_hardware_watchpoints =
@@ -286,7 +286,7 @@ class CommandObjectWatchpointEnable : public CommandObjectParsed {
 
 protected:
   void DoExecute(Args &command, CommandReturnObject &result) override {
-    Target *target = &GetSelectedTarget();
+    Target *target = &GetTarget();
     if (!CheckTargetForWatchpointOperations(target, result))
       return;
 
@@ -355,7 +355,7 @@ class CommandObjectWatchpointDisable : public CommandObjectParsed {
 
 protected:
   void DoExecute(Args &command, CommandReturnObject &result) override {
-    Target *target = &GetSelectedTarget();
+    Target *target = &GetTarget();
     if (!CheckTargetForWatchpointOperations(target, result))
       return;
 
@@ -464,7 +464,7 @@ class CommandObjectWatchpointDelete : public CommandObjectParsed {
 
 protected:
   void DoExecute(Args &command, CommandReturnObject &result) override {
-    Target *target = &GetSelectedTarget();
+    Target *target = &GetTarget();
     if (!CheckTargetForWatchpointOperations(target, result))
       return;
 
@@ -584,7 +584,7 @@ class CommandObjectWatchpointIgnore : public CommandObjectParsed {
 
 protected:
   void DoExecute(Args &command, CommandReturnObject &result) override {
-    Target *target = &GetSelectedTarget();
+    Target *target = &GetTarget();
     if (!CheckTargetForWatchpointOperations(target, result))
       return;
 
@@ -703,7 +703,7 @@ class CommandObjectWatchpointModify : public CommandObjectParsed {
 
 protected:
   void DoExecute(Args &command, CommandReturnObject &result) override {
-    Target *target = &GetSelectedTarget();
+    Target *target = &GetTarget();
     if (!CheckTargetForWatchpointOperations(target, result))
       return;
 
@@ -804,7 +804,7 @@ corresponding to the byte size of the data type.");
   }
 
   void DoExecute(Args &command, CommandReturnObject &result) override {
-    Target *target = GetDebugger().GetSelectedTarget().get();
+    Target *target = &GetTarget();
     StackFrame *frame = m_exe_ctx.GetFramePtr();
 
     // If no argument is present, issue an error message.  There's no way to
@@ -991,7 +991,7 @@ class CommandObjectWatchpointSetExpression : public CommandObjectRaw {
     m_option_group.NotifyOptionParsingStarting(
         &exe_ctx); // This is a raw command, so notify the option group
 
-    Target *target = GetDebugger().GetSelectedTarget().get();
+    Target *target = &GetTarget();
     StackFrame *frame = m_exe_ctx.GetFramePtr();
 
     OptionsWithRaw args(raw_command);
diff --git a/lldb/source/Commands/CommandObjectWatchpointCommand.cpp b/lldb/source/Commands/CommandObjectWatchpointCommand.cpp
index aaf14540cb282..b4743eb3d8757 100644
--- a/lldb/source/Commands/CommandObjectWatchpointCommand.cpp
+++ b/lldb/source/Commands/CommandObjectWatchpointCommand.cpp
@@ -355,7 +355,7 @@ are no syntax errors may indicate that a function was declared but never called.
 
 protected:
   void DoExecute(Args &command, CommandReturnObject &result) override {
-    Target *target = &GetSelectedTarget();
+    Target *target = &GetTarget();
 
     const WatchpointList &watchpoints = target->GetWatchpointList();
     size_t num_watchpoints = watchpoints.GetSize();
@@ -450,7 +450,7 @@ class CommandObjectWatchpointCommandDelete : public CommandObjectParsed {
 
 protected:
   void DoExecute(Args &command, CommandReturnObject &result) override {
-    Target *target = &GetSelectedTarget();
+    Target *target = &GetTarget();
 
     const WatchpointList &watchpoints = target->GetWatchpointList();
     size_t num_watchpoints = watchpoints.GetSize();
@@ -505,7 +505,7 @@ class CommandObjectWatchpointCommandList : public CommandObjectParsed {
 
 protected:
   void DoExecute(Args &command, CommandReturnObject &result) override {
-    Target *target = &GetSelectedTarget();
+    Target *target = &GetTarget();
 
     const WatchpointList &watchpoints = target->GetWatchpointList();
     size_t num_watchpoints = watchpoints.GetSize();
diff --git a/lldb/source/Interpreter/CommandObject.cpp b/lldb/source/Interpreter/CommandObject.cpp
index 4634b75c6a33a..b2b1ab791be83 100644
--- a/lldb/source/Interpreter/CommandObject.cpp
+++ b/lldb/source/Interpreter/CommandObject.cpp
@@ -754,23 +754,29 @@ const char *CommandObject::GetArgumentDescriptionAsCString(
   return g_argument_table[arg_type].help_text;
 }
 
-Target &CommandObject::GetDummyTarget() {
+Target &CommandObject::GetTarget(bool dummy) {
+  // Always return the dummy target if explicitly requested.
+  if (dummy)
+    return m_interpreter.GetDebugger().GetDummyTarget();
+
+  // Prefer the frozen execution context in the command object.
+  if (Target *target = m_exe_ctx.GetTargetPtr())
+    return *target;
+
+  // Fallback to the command interpreter's execution context in case we get
+  // called after DoExecute has finished. For example, when doing multi-line
+  // expression that uses an input reader or breakpoint callbacks.
+  if (Target *target = m_interpreter.GetExecutionContext().GetTargetPtr())
+    return *target;
+
+  // Finally, if we have no other target, get the selected target.
+  if (TargetSP target_sp = m_interpreter.GetDebugger().GetSelectedTarget())
+    return *target_sp;
+
+  // We only have the dummy target.
   return m_interpreter.GetDebugger().GetDummyTarget();
 }
 
-Target &CommandObject::GetSelectedOrDummyTarget(bool prefer_dummy) {
-  return m_interpreter.GetDebugger().GetSelectedOrDummyTarget(prefer_dummy);
-}
-
-Target &CommandObject::GetSelectedTarget() {
-  assert(m_flags.AnySet(eCommandRequiresTarget | eCommandProcessMustBePaused |
-                        eCommandProcessMustBeLaunched | eCommandRequiresFrame |
-                        eCommandRequiresThread | eCommandRequiresProcess |
-                        eCommandRequiresRegContext) &&
-         "GetSelectedTarget called from object that may have no target");
-  return *m_interpreter.GetDebugger().GetSelectedTarget();
-}
-
 Thread *CommandObject::GetDefaultThread() {
   Thread *thread_to_use = m_exe_ctx.GetThreadPtr();
   if (thread_to_use)
diff --git a/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp b/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp
index c46dc54c912e5..07245479fc2cd 100644
--- a/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp
+++ b/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp
@@ -783,7 +783,7 @@ class EnableCommand : public CommandObjectParsed {
 
     // Now check if we have a running process.  If so, we should instruct the
     // process monitor to enable/disable DarwinLog support now.
-    Target &target = GetSelectedOrDummyTarget();
+    Target &target = GetTarget();
 
     // Grab the active process.
     auto process_sp = target.GetProcessSP();
@@ -865,7 +865,7 @@ class StatusCommand : public CommandObjectParsed {
 
     // Figure out if we've got a process.  If so, we can tell if DarwinLog is
     // available for that process.
-    Target &target = GetSelectedOrDummyTarget();
+    Target &target = GetTarget();
     auto process_sp = target.GetProcessSP();
     if (!process_sp) {
       stream.PutCString("Availability: unknown (requires process)\n");



More information about the lldb-commits mailing list