[Lldb-commits] [lldb] [lldb] add stop-at-user-entry option to process launch (PR #67019)

José Lira Junior via lldb-commits lldb-commits at lists.llvm.org
Fri Sep 29 11:15:49 PDT 2023


https://github.com/junior-jl updated https://github.com/llvm/llvm-project/pull/67019

>From 9130096419bd3211af0163ec28ba9471de398d47 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jos=C3=A9=20L=2E=20Junior?= <jljuniorpb at gmail.com>
Date: Thu, 21 Sep 2023 11:12:58 -0300
Subject: [PATCH 1/9] [lldb] add command start

---
 lldb/source/Commands/CMakeLists.txt           |   1 +
 lldb/source/Commands/CommandObjectStart.cpp   | 102 ++++++++++++++++++
 lldb/source/Commands/CommandObjectStart.h     |  32 ++++++
 .../source/Interpreter/CommandInterpreter.cpp |   2 +
 4 files changed, 137 insertions(+)
 create mode 100644 lldb/source/Commands/CommandObjectStart.cpp
 create mode 100644 lldb/source/Commands/CommandObjectStart.h

diff --git a/lldb/source/Commands/CMakeLists.txt b/lldb/source/Commands/CMakeLists.txt
index 6a36c5376d5c574..54c62e0f5284beb 100644
--- a/lldb/source/Commands/CMakeLists.txt
+++ b/lldb/source/Commands/CMakeLists.txt
@@ -30,6 +30,7 @@ add_lldb_library(lldbCommands NO_PLUGIN_DEPENDENCIES
   CommandObjectSession.cpp
   CommandObjectSettings.cpp
   CommandObjectSource.cpp
+  CommandObjectStart.cpp
   CommandObjectStats.cpp
   CommandObjectTarget.cpp
   CommandObjectThread.cpp
diff --git a/lldb/source/Commands/CommandObjectStart.cpp b/lldb/source/Commands/CommandObjectStart.cpp
new file mode 100644
index 000000000000000..7406143c50fec1b
--- /dev/null
+++ b/lldb/source/Commands/CommandObjectStart.cpp
@@ -0,0 +1,102 @@
+//===-- CommandObjectStart.cpp -------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "CommandObjectStart.h"
+#include "lldb/Interpreter/CommandObject.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+// Constructor for CommandObjectStart
+CommandObjectStart::CommandObjectStart(CommandInterpreter &interpreter)
+    : CommandObjectParsed(
+          interpreter, "start",
+          "Launches the process and pauses execution at main function",
+          "start args [optional args]") {
+  // Define command arguments
+  CommandArgumentData pause_location{eArgTypeName, eArgRepeatPlain};
+  m_arguments.push_back({pause_location});
+}
+
+CommandObjectStart::~CommandObjectStart() = default;
+
+// Execute the 'start' command
+bool CommandObjectStart::DoExecute(Args &command, CommandReturnObject &result) {
+  // Check if the 'first' subcommand is specified
+  bool pause_at_first_instruction = false;
+
+  if (command.GetArgumentCount() == 1 &&
+      strcmp(command.GetArgumentAtIndex(0), "first") == 0) {
+    pause_at_first_instruction = true;
+  }
+
+  // Get the current selected target
+  TargetSP target_sp = GetDebugger().GetSelectedTarget();
+  if (!target_sp) {
+    result.AppendError("No target selected.\n");
+    return false;
+  }
+
+  // Create the breakpoint at main or the first instruction
+  BreakpointSP bp_sp;
+  if (pause_at_first_instruction) {
+    ModuleSP exe_module_sp = target_sp->GetExecutableModule();
+    ObjectFile *object = exe_module_sp->GetObjectFile();
+    Address address = object->GetEntryPointAddress();
+
+    if (!address.IsValid()) {
+      result.AppendError("Failed to get the entry point address");
+      result.SetStatus(eReturnStatusFailed);
+      return false;
+    }
+
+    bp_sp = target_sp->CreateBreakpoint(address, false, false);
+
+  } else {
+    // Create a breakpoint at the main function
+    bp_sp = target_sp->CreateBreakpoint(
+        nullptr, nullptr, "main", eFunctionNameTypeAuto, eLanguageTypeUnknown,
+        0, eLazyBoolNo, false, false);
+  }
+
+  if (!bp_sp) {
+    result.AppendError("Breakpoint creation failed.\n");
+    result.SetStatus(eReturnStatusFailed);
+    return false;
+  } else {
+    result.GetOutputStream().Printf("Breakpoint created%s.\n",
+                                    pause_at_first_instruction
+                                        ? " at first instruction"
+                                        : " in main function");
+    result.SetStatus(eReturnStatusSuccessFinishResult);
+  }
+
+  // Construct the process launch info
+  ProcessLaunchInfo launch_info;
+  launch_info.SetShell(HostInfo::GetDefaultShell());
+  ModuleSP exe_module_sp = target_sp->GetExecutableModule();
+  if (!exe_module_sp) {
+    result.AppendError("No executable module found.\n");
+    return false;
+  }
+
+  launch_info.SetExecutableFile(exe_module_sp->GetPlatformFileSpec(), true);
+  // Launch the process
+  StreamString stream;
+  Status error = target_sp->Launch(launch_info, &stream);
+
+  if (error.Success()) {
+    result.SetStatus(eReturnStatusSuccessFinishResult);
+    result.GetOutputStream().Printf("Process launched successfully.\n");
+  } else {
+    result.AppendErrorWithFormat("Process launch failed: %s\n",
+                                 error.AsCString());
+    return false;
+  }
+  return result.Succeeded();
+}
diff --git a/lldb/source/Commands/CommandObjectStart.h b/lldb/source/Commands/CommandObjectStart.h
new file mode 100644
index 000000000000000..8475a17c347f7be
--- /dev/null
+++ b/lldb/source/Commands/CommandObjectStart.h
@@ -0,0 +1,32 @@
+//===-- CommandObjectStart.h ---------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTStart_H
+#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTStart_H
+
+#include "lldb/Core/Module.h"
+#include "lldb/Host/HostInfo.h"
+#include "lldb/Host/ProcessLaunchInfo.h"
+#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Interpreter/CommandObject.h"
+#include "lldb/Interpreter/CommandObjectMultiword.h"
+#include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Symbol/SymbolContext.h"
+
+namespace lldb_private {
+class CommandObjectStart : public CommandObjectParsed {
+public:
+  CommandObjectStart(CommandInterpreter &interpreter);
+  ~CommandObjectStart() override;
+
+protected:
+  bool DoExecute(Args &args, CommandReturnObject &result) override;
+};
+} // namespace lldb_private
+
+#endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTStart_H
diff --git a/lldb/source/Interpreter/CommandInterpreter.cpp b/lldb/source/Interpreter/CommandInterpreter.cpp
index dcff53ff843f328..5d6ad7f0dbb1e8e 100644
--- a/lldb/source/Interpreter/CommandInterpreter.cpp
+++ b/lldb/source/Interpreter/CommandInterpreter.cpp
@@ -36,6 +36,7 @@
 #include "Commands/CommandObjectSession.h"
 #include "Commands/CommandObjectSettings.h"
 #include "Commands/CommandObjectSource.h"
+#include "Commands/CommandObjectStart.h"
 #include "Commands/CommandObjectStats.h"
 #include "Commands/CommandObjectTarget.h"
 #include "Commands/CommandObjectThread.h"
@@ -559,6 +560,7 @@ void CommandInterpreter::LoadCommandDictionary() {
   REGISTER_COMMAND_OBJECT("settings", CommandObjectMultiwordSettings);
   REGISTER_COMMAND_OBJECT("session", CommandObjectSession);
   REGISTER_COMMAND_OBJECT("source", CommandObjectMultiwordSource);
+  REGISTER_COMMAND_OBJECT("start", CommandObjectStart);
   REGISTER_COMMAND_OBJECT("statistics", CommandObjectStats);
   REGISTER_COMMAND_OBJECT("target", CommandObjectMultiwordTarget);
   REGISTER_COMMAND_OBJECT("thread", CommandObjectMultiwordThread);

>From 7f8714ddf8f1ae6a182456f0551d0b64bb948fc8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jos=C3=A9=20L=2E=20Junior?= <jljuniorpb at gmail.com>
Date: Fri, 22 Sep 2023 12:13:25 -0300
Subject: [PATCH 2/9] [lldb] add stop-at-main option to process launch

---
 .../source/Commands/CommandOptionsProcessLaunch.cpp | 13 ++++++++++++-
 lldb/source/Commands/Options.td                     |  2 ++
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/lldb/source/Commands/CommandOptionsProcessLaunch.cpp b/lldb/source/Commands/CommandOptionsProcessLaunch.cpp
index 85ad8ff5e07132c..9f8d3047159cd72 100644
--- a/lldb/source/Commands/CommandOptionsProcessLaunch.cpp
+++ b/lldb/source/Commands/CommandOptionsProcessLaunch.cpp
@@ -38,7 +38,18 @@ Status CommandOptionsProcessLaunch::SetOptionValue(
   case 's': // Stop at program entry point
     launch_info.GetFlags().Set(eLaunchFlagStopAtEntry);
     break;
-
+  case 'm': // Stop at main function
+  {
+    TargetSP target_sp =
+        execution_context ? execution_context->GetTargetSP() : TargetSP();
+    BreakpointSP bp_sp = target_sp->CreateBreakpoint(
+        nullptr, nullptr, "main", eFunctionNameTypeAuto, eLanguageTypeUnknown,
+        0, eLazyBoolNo, false, false);
+    if (!bp_sp)
+      error.SetErrorString("Breakpoint creation failed.\n");
+    launch_info.SetShell(HostInfo::GetDefaultShell());
+    break;
+  }
   case 'i': // STDIN for read only
   {
     FileAction action;
diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td
index 04830b8b990efae..af2e662c05a5b47 100644
--- a/lldb/source/Commands/Options.td
+++ b/lldb/source/Commands/Options.td
@@ -675,6 +675,8 @@ let Command = "platform shell" in {
 let Command = "process launch" in {
   def process_launch_stop_at_entry : Option<"stop-at-entry", "s">,
     Desc<"Stop at the entry point of the program when launching a process.">;
+  def process_launch_stop_at_main : Option<"stop-at-main", "m">,
+    Desc<"Stop at the main function of the program when launching a process.">;
   def process_launch_disable_aslr : Option<"disable-aslr", "A">, Arg<"Boolean">,
     Desc<"Set whether to disable address space layout randomization when launching a process.">;
   def process_launch_plugin : Option<"plugin", "P">, Arg<"Plugin">,

>From f633e17d187c41383cabef87076f3080542766cf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jos=C3=A9=20L=2E=20Junior?= <jljuniorpb at gmail.com>
Date: Mon, 25 Sep 2023 17:59:27 -0300
Subject: [PATCH 3/9] Revert "[lldb] add command start"

This reverts commit 11270775865a8415e00b4d899703f84717344967.
---
 lldb/source/Commands/CMakeLists.txt           |   1 -
 lldb/source/Commands/CommandObjectStart.cpp   | 102 ------------------
 lldb/source/Commands/CommandObjectStart.h     |  32 ------
 .../source/Interpreter/CommandInterpreter.cpp |   2 -
 4 files changed, 137 deletions(-)
 delete mode 100644 lldb/source/Commands/CommandObjectStart.cpp
 delete mode 100644 lldb/source/Commands/CommandObjectStart.h

diff --git a/lldb/source/Commands/CMakeLists.txt b/lldb/source/Commands/CMakeLists.txt
index 54c62e0f5284beb..6a36c5376d5c574 100644
--- a/lldb/source/Commands/CMakeLists.txt
+++ b/lldb/source/Commands/CMakeLists.txt
@@ -30,7 +30,6 @@ add_lldb_library(lldbCommands NO_PLUGIN_DEPENDENCIES
   CommandObjectSession.cpp
   CommandObjectSettings.cpp
   CommandObjectSource.cpp
-  CommandObjectStart.cpp
   CommandObjectStats.cpp
   CommandObjectTarget.cpp
   CommandObjectThread.cpp
diff --git a/lldb/source/Commands/CommandObjectStart.cpp b/lldb/source/Commands/CommandObjectStart.cpp
deleted file mode 100644
index 7406143c50fec1b..000000000000000
--- a/lldb/source/Commands/CommandObjectStart.cpp
+++ /dev/null
@@ -1,102 +0,0 @@
-//===-- CommandObjectStart.cpp -------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "CommandObjectStart.h"
-#include "lldb/Interpreter/CommandObject.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-// Constructor for CommandObjectStart
-CommandObjectStart::CommandObjectStart(CommandInterpreter &interpreter)
-    : CommandObjectParsed(
-          interpreter, "start",
-          "Launches the process and pauses execution at main function",
-          "start args [optional args]") {
-  // Define command arguments
-  CommandArgumentData pause_location{eArgTypeName, eArgRepeatPlain};
-  m_arguments.push_back({pause_location});
-}
-
-CommandObjectStart::~CommandObjectStart() = default;
-
-// Execute the 'start' command
-bool CommandObjectStart::DoExecute(Args &command, CommandReturnObject &result) {
-  // Check if the 'first' subcommand is specified
-  bool pause_at_first_instruction = false;
-
-  if (command.GetArgumentCount() == 1 &&
-      strcmp(command.GetArgumentAtIndex(0), "first") == 0) {
-    pause_at_first_instruction = true;
-  }
-
-  // Get the current selected target
-  TargetSP target_sp = GetDebugger().GetSelectedTarget();
-  if (!target_sp) {
-    result.AppendError("No target selected.\n");
-    return false;
-  }
-
-  // Create the breakpoint at main or the first instruction
-  BreakpointSP bp_sp;
-  if (pause_at_first_instruction) {
-    ModuleSP exe_module_sp = target_sp->GetExecutableModule();
-    ObjectFile *object = exe_module_sp->GetObjectFile();
-    Address address = object->GetEntryPointAddress();
-
-    if (!address.IsValid()) {
-      result.AppendError("Failed to get the entry point address");
-      result.SetStatus(eReturnStatusFailed);
-      return false;
-    }
-
-    bp_sp = target_sp->CreateBreakpoint(address, false, false);
-
-  } else {
-    // Create a breakpoint at the main function
-    bp_sp = target_sp->CreateBreakpoint(
-        nullptr, nullptr, "main", eFunctionNameTypeAuto, eLanguageTypeUnknown,
-        0, eLazyBoolNo, false, false);
-  }
-
-  if (!bp_sp) {
-    result.AppendError("Breakpoint creation failed.\n");
-    result.SetStatus(eReturnStatusFailed);
-    return false;
-  } else {
-    result.GetOutputStream().Printf("Breakpoint created%s.\n",
-                                    pause_at_first_instruction
-                                        ? " at first instruction"
-                                        : " in main function");
-    result.SetStatus(eReturnStatusSuccessFinishResult);
-  }
-
-  // Construct the process launch info
-  ProcessLaunchInfo launch_info;
-  launch_info.SetShell(HostInfo::GetDefaultShell());
-  ModuleSP exe_module_sp = target_sp->GetExecutableModule();
-  if (!exe_module_sp) {
-    result.AppendError("No executable module found.\n");
-    return false;
-  }
-
-  launch_info.SetExecutableFile(exe_module_sp->GetPlatformFileSpec(), true);
-  // Launch the process
-  StreamString stream;
-  Status error = target_sp->Launch(launch_info, &stream);
-
-  if (error.Success()) {
-    result.SetStatus(eReturnStatusSuccessFinishResult);
-    result.GetOutputStream().Printf("Process launched successfully.\n");
-  } else {
-    result.AppendErrorWithFormat("Process launch failed: %s\n",
-                                 error.AsCString());
-    return false;
-  }
-  return result.Succeeded();
-}
diff --git a/lldb/source/Commands/CommandObjectStart.h b/lldb/source/Commands/CommandObjectStart.h
deleted file mode 100644
index 8475a17c347f7be..000000000000000
--- a/lldb/source/Commands/CommandObjectStart.h
+++ /dev/null
@@ -1,32 +0,0 @@
-//===-- CommandObjectStart.h ---------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTStart_H
-#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTStart_H
-
-#include "lldb/Core/Module.h"
-#include "lldb/Host/HostInfo.h"
-#include "lldb/Host/ProcessLaunchInfo.h"
-#include "lldb/Interpreter/CommandInterpreter.h"
-#include "lldb/Interpreter/CommandObject.h"
-#include "lldb/Interpreter/CommandObjectMultiword.h"
-#include "lldb/Interpreter/CommandReturnObject.h"
-#include "lldb/Symbol/SymbolContext.h"
-
-namespace lldb_private {
-class CommandObjectStart : public CommandObjectParsed {
-public:
-  CommandObjectStart(CommandInterpreter &interpreter);
-  ~CommandObjectStart() override;
-
-protected:
-  bool DoExecute(Args &args, CommandReturnObject &result) override;
-};
-} // namespace lldb_private
-
-#endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTStart_H
diff --git a/lldb/source/Interpreter/CommandInterpreter.cpp b/lldb/source/Interpreter/CommandInterpreter.cpp
index 5d6ad7f0dbb1e8e..dcff53ff843f328 100644
--- a/lldb/source/Interpreter/CommandInterpreter.cpp
+++ b/lldb/source/Interpreter/CommandInterpreter.cpp
@@ -36,7 +36,6 @@
 #include "Commands/CommandObjectSession.h"
 #include "Commands/CommandObjectSettings.h"
 #include "Commands/CommandObjectSource.h"
-#include "Commands/CommandObjectStart.h"
 #include "Commands/CommandObjectStats.h"
 #include "Commands/CommandObjectTarget.h"
 #include "Commands/CommandObjectThread.h"
@@ -560,7 +559,6 @@ void CommandInterpreter::LoadCommandDictionary() {
   REGISTER_COMMAND_OBJECT("settings", CommandObjectMultiwordSettings);
   REGISTER_COMMAND_OBJECT("session", CommandObjectSession);
   REGISTER_COMMAND_OBJECT("source", CommandObjectMultiwordSource);
-  REGISTER_COMMAND_OBJECT("start", CommandObjectStart);
   REGISTER_COMMAND_OBJECT("statistics", CommandObjectStats);
   REGISTER_COMMAND_OBJECT("target", CommandObjectMultiwordTarget);
   REGISTER_COMMAND_OBJECT("thread", CommandObjectMultiwordThread);

>From e9f4dfa41c1d472cb01fa7a23275d7a1d561ca9f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jos=C3=A9=20L=2E=20Junior?= <jljuniorpb at gmail.com>
Date: Mon, 25 Sep 2023 18:14:32 -0300
Subject: [PATCH 4/9] [lldb] remove shell modification | make bp one-shot

---
 lldb/source/Commands/CommandOptionsProcessLaunch.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lldb/source/Commands/CommandOptionsProcessLaunch.cpp b/lldb/source/Commands/CommandOptionsProcessLaunch.cpp
index 9f8d3047159cd72..b49d5936e5ba4af 100644
--- a/lldb/source/Commands/CommandOptionsProcessLaunch.cpp
+++ b/lldb/source/Commands/CommandOptionsProcessLaunch.cpp
@@ -47,7 +47,7 @@ Status CommandOptionsProcessLaunch::SetOptionValue(
         0, eLazyBoolNo, false, false);
     if (!bp_sp)
       error.SetErrorString("Breakpoint creation failed.\n");
-    launch_info.SetShell(HostInfo::GetDefaultShell());
+    bp_sp->SetOneShot(true);
     break;
   }
   case 'i': // STDIN for read only

>From bcb56611544f71648c9fde453dc54d4c8ace9fc8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jos=C3=A9=20L=2E=20Junior?= <jljuniorpb at gmail.com>
Date: Tue, 26 Sep 2023 15:46:23 -0300
Subject: [PATCH 5/9] add GetUserEntryPointName method | changed bp creating
 method

---
 lldb/include/lldb/Target/Language.h           | 20 +++++++++++----
 .../Commands/CommandOptionsProcessLaunch.cpp  | 25 ++++++++++++++++---
 lldb/source/Commands/Options.td               |  4 +--
 .../Language/CPlusPlus/CPlusPlusLanguage.h    |  2 ++
 .../Plugins/Language/ObjC/ObjCLanguage.h      |  2 ++
 .../ObjCPlusPlus/ObjCPlusPlusLanguage.h       |  2 ++
 6 files changed, 45 insertions(+), 10 deletions(-)

diff --git a/lldb/include/lldb/Target/Language.h b/lldb/include/lldb/Target/Language.h
index a6b9ccaf31b3c42..943c7f0d3df8d65 100644
--- a/lldb/include/lldb/Target/Language.h
+++ b/lldb/include/lldb/Target/Language.h
@@ -95,21 +95,24 @@ class Language : public PluginInterface {
   class EitherTypeScavenger : public TypeScavenger {
   public:
     EitherTypeScavenger() : TypeScavenger() {
-      for (std::shared_ptr<TypeScavenger> scavenger : { std::shared_ptr<TypeScavenger>(new ScavengerTypes())... }) {
+      for (std::shared_ptr<TypeScavenger> scavenger :
+           {std::shared_ptr<TypeScavenger>(new ScavengerTypes())...}) {
         if (scavenger)
           m_scavengers.push_back(scavenger);
       }
     }
+
   protected:
     bool Find_Impl(ExecutionContextScope *exe_scope, const char *key,
                    ResultSet &results) override {
       const bool append = false;
-      for (auto& scavenger : m_scavengers) {
+      for (auto &scavenger : m_scavengers) {
         if (scavenger && scavenger->Find(exe_scope, key, results, append))
           return true;
       }
       return false;
     }
+
   private:
     std::vector<std::shared_ptr<TypeScavenger>> m_scavengers;
   };
@@ -118,22 +121,25 @@ class Language : public PluginInterface {
   class UnionTypeScavenger : public TypeScavenger {
   public:
     UnionTypeScavenger() : TypeScavenger() {
-      for (std::shared_ptr<TypeScavenger> scavenger : { std::shared_ptr<TypeScavenger>(new ScavengerTypes())... }) {
+      for (std::shared_ptr<TypeScavenger> scavenger :
+           {std::shared_ptr<TypeScavenger>(new ScavengerTypes())...}) {
         if (scavenger)
           m_scavengers.push_back(scavenger);
       }
     }
+
   protected:
     bool Find_Impl(ExecutionContextScope *exe_scope, const char *key,
                    ResultSet &results) override {
       const bool append = true;
       bool success = false;
-      for (auto& scavenger : m_scavengers) {
+      for (auto &scavenger : m_scavengers) {
         if (scavenger)
           success = scavenger->Find(exe_scope, key, results, append) || success;
       }
       return success;
     }
+
   private:
     std::vector<std::shared_ptr<TypeScavenger>> m_scavengers;
   };
@@ -160,6 +166,10 @@ class Language : public PluginInterface {
 
   virtual lldb::LanguageType GetLanguageType() const = 0;
 
+  // Implement this function to return the user-defined entry point name
+  // for the language
+  virtual const char *GetUserEntryPointName() const { return nullptr; }
+
   virtual bool IsTopLevelFunction(Function &function);
 
   virtual bool IsSourceFile(llvm::StringRef file_path) const = 0;
@@ -232,7 +242,7 @@ class Language : public PluginInterface {
   // a match.  But we wouldn't want this to match AnotherA::my_function.  The
   // user is specifying a truncated path, not a truncated set of characters.
   // This function does a language-aware comparison for those purposes.
-  virtual bool DemangledNameContainsPath(llvm::StringRef path, 
+  virtual bool DemangledNameContainsPath(llvm::StringRef path,
                                          ConstString demangled) const;
 
   // if a language has a custom format for printing variable declarations that
diff --git a/lldb/source/Commands/CommandOptionsProcessLaunch.cpp b/lldb/source/Commands/CommandOptionsProcessLaunch.cpp
index b49d5936e5ba4af..a999a415311dc11 100644
--- a/lldb/source/Commands/CommandOptionsProcessLaunch.cpp
+++ b/lldb/source/Commands/CommandOptionsProcessLaunch.cpp
@@ -16,6 +16,7 @@
 #include "lldb/Interpreter/CommandOptionArgumentTable.h"
 #include "lldb/Interpreter/OptionArgParser.h"
 #include "lldb/Target/ExecutionContext.h"
+#include "lldb/Target/Language.h"
 #include "lldb/Target/Platform.h"
 #include "lldb/Target/Target.h"
 
@@ -38,13 +39,31 @@ Status CommandOptionsProcessLaunch::SetOptionValue(
   case 's': // Stop at program entry point
     launch_info.GetFlags().Set(eLaunchFlagStopAtEntry);
     break;
-  case 'm': // Stop at main function
+  case 'm': // Stop at user entry point
   {
     TargetSP target_sp =
         execution_context ? execution_context->GetTargetSP() : TargetSP();
+    ModuleSP main_module_sp = target_sp->GetExecutableModule();
+    FileSpecList shared_lib_filter;
+    shared_lib_filter.Append(main_module_sp->GetFileSpec());
+    std::vector<std::string> entryPointNames;
+    for (LanguageType lang_type : Language::GetSupportedLanguages()) {
+      Language *lang = Language::FindPlugin(lang_type);
+      if (lang) {
+        std::string entryPointName = lang->GetUserEntryPointName();
+        if (!entryPointName.empty()) {
+          entryPointNames.push_back(entryPointName);
+        }
+      }
+    }
     BreakpointSP bp_sp = target_sp->CreateBreakpoint(
-        nullptr, nullptr, "main", eFunctionNameTypeAuto, eLanguageTypeUnknown,
-        0, eLazyBoolNo, false, false);
+        /*containingModules=*/&shared_lib_filter,
+        /*containingSourceFiles=*/nullptr,
+        /*func_names=*/entryPointNames,
+        /*func_name_type_mask=*/eFunctionNameTypeFull,
+        /*language=*/eLanguageTypeUnknown,
+        /*offset=*/0, /*skip_prologue=*/eLazyBoolNo, /*internal=*/false,
+        /*hardware=*/false);
     if (!bp_sp)
       error.SetErrorString("Breakpoint creation failed.\n");
     bp_sp->SetOneShot(true);
diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td
index af2e662c05a5b47..e119d287b19242c 100644
--- a/lldb/source/Commands/Options.td
+++ b/lldb/source/Commands/Options.td
@@ -675,8 +675,8 @@ let Command = "platform shell" in {
 let Command = "process launch" in {
   def process_launch_stop_at_entry : Option<"stop-at-entry", "s">,
     Desc<"Stop at the entry point of the program when launching a process.">;
-  def process_launch_stop_at_main : Option<"stop-at-main", "m">,
-    Desc<"Stop at the main function of the program when launching a process.">;
+  def process_launch_stop_at_main : Option<"stop-at-user-entry", "m">,
+    Desc<"Stop at the user entry point when launching a process.">;
   def process_launch_disable_aslr : Option<"disable-aslr", "A">, Arg<"Boolean">,
     Desc<"Set whether to disable address space layout randomization when launching a process.">;
   def process_launch_plugin : Option<"plugin", "P">, Arg<"Plugin">,
diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h
index 7712a60b7795951..8da28e5300594ca 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h
+++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h
@@ -103,6 +103,8 @@ class CPlusPlusLanguage : public Language {
     return lldb::eLanguageTypeC_plus_plus;
   }
 
+  const char *GetUserEntryPointName() const override { return "main"; }
+  
   std::unique_ptr<TypeScavenger> GetTypeScavenger() override;
   lldb::TypeCategoryImplSP GetFormatters() override;
 
diff --git a/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h b/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h
index bb8057846bb7c30..f2ce8c050fc35ce 100644
--- a/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h
+++ b/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h
@@ -127,6 +127,8 @@ class ObjCLanguage : public Language {
     return lldb::eLanguageTypeObjC;
   }
 
+  const char *GetUserEntryPointName() const override { return "main"; }
+
   // Get all possible names for a method. Examples:
   // If method_name is "+[NSString(my_additions) myStringWithCString:]"
   //   variant_names[0] => "+[NSString myStringWithCString:]"
diff --git a/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h b/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h
index b7c71b5dbb1c991..74d503d1ffcf810 100644
--- a/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h
+++ b/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h
@@ -27,6 +27,8 @@ class ObjCPlusPlusLanguage : public Language {
     return lldb::eLanguageTypeObjC_plus_plus;
   }
 
+  const char *GetUserEntryPointName() const override { return "main"; }
+  
   llvm::StringRef GetNilReferenceSummaryString() override { return "nil"; }
 
   bool IsSourceFile(llvm::StringRef file_path) const override;

>From 720d74c419b8937f0f0a13f7a98a8c0f0858ee38 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jos=C3=A9=20L=2E=20Junior?= <jljuniorpb at gmail.com>
Date: Tue, 26 Sep 2023 16:07:10 -0300
Subject: [PATCH 6/9] use clang-format

---
 lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h  | 6 +++---
 .../Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h    | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h
index 8da28e5300594ca..648b6e2006b3473 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h
+++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h
@@ -104,7 +104,7 @@ class CPlusPlusLanguage : public Language {
   }
 
   const char *GetUserEntryPointName() const override { return "main"; }
-  
+
   std::unique_ptr<TypeScavenger> GetTypeScavenger() override;
   lldb::TypeCategoryImplSP GetFormatters() override;
 
@@ -131,8 +131,8 @@ class CPlusPlusLanguage : public Language {
   static llvm::StringRef GetPluginNameStatic() { return "cplusplus"; }
 
   bool SymbolNameFitsToLanguage(Mangled mangled) const override;
-  
-  bool DemangledNameContainsPath(llvm::StringRef path, 
+
+  bool DemangledNameContainsPath(llvm::StringRef path,
                                  ConstString demangled) const override;
 
   ConstString
diff --git a/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h b/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h
index 74d503d1ffcf810..177bb3517557fe4 100644
--- a/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h
+++ b/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h
@@ -28,7 +28,7 @@ class ObjCPlusPlusLanguage : public Language {
   }
 
   const char *GetUserEntryPointName() const override { return "main"; }
-  
+
   llvm::StringRef GetNilReferenceSummaryString() override { return "nil"; }
 
   bool IsSourceFile(llvm::StringRef file_path) const override;

>From 2f9e41a6940901a8aa1cfc78adf671d9b10fe4fc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jos=C3=A9=20L=2E=20Junior?= <jljuniorpb at gmail.com>
Date: Wed, 27 Sep 2023 11:25:12 -0300
Subject: [PATCH 7/9] change option description | using set for entrypoint
 names

---
 lldb/source/Commands/CommandOptionsProcessLaunch.cpp | 9 +++++----
 lldb/source/Commands/Options.td                      | 6 ++++--
 2 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/lldb/source/Commands/CommandOptionsProcessLaunch.cpp b/lldb/source/Commands/CommandOptionsProcessLaunch.cpp
index a999a415311dc11..a71ee5db8f2f27c 100644
--- a/lldb/source/Commands/CommandOptionsProcessLaunch.cpp
+++ b/lldb/source/Commands/CommandOptionsProcessLaunch.cpp
@@ -46,16 +46,17 @@ Status CommandOptionsProcessLaunch::SetOptionValue(
     ModuleSP main_module_sp = target_sp->GetExecutableModule();
     FileSpecList shared_lib_filter;
     shared_lib_filter.Append(main_module_sp->GetFileSpec());
-    std::vector<std::string> entryPointNames;
+    std::set<std::string> entryPointNamesSet;
     for (LanguageType lang_type : Language::GetSupportedLanguages()) {
       Language *lang = Language::FindPlugin(lang_type);
       if (lang) {
         std::string entryPointName = lang->GetUserEntryPointName();
-        if (!entryPointName.empty()) {
-          entryPointNames.push_back(entryPointName);
-        }
+        if (!entryPointName.empty())
+          entryPointNamesSet.insert(entryPointName);
       }
     }
+    std::vector<std::string> entryPointNames(entryPointNamesSet.begin(),
+                                             entryPointNamesSet.end());
     BreakpointSP bp_sp = target_sp->CreateBreakpoint(
         /*containingModules=*/&shared_lib_filter,
         /*containingSourceFiles=*/nullptr,
diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td
index e119d287b19242c..dd4cf5c4dc043e7 100644
--- a/lldb/source/Commands/Options.td
+++ b/lldb/source/Commands/Options.td
@@ -675,8 +675,10 @@ let Command = "platform shell" in {
 let Command = "process launch" in {
   def process_launch_stop_at_entry : Option<"stop-at-entry", "s">,
     Desc<"Stop at the entry point of the program when launching a process.">;
-  def process_launch_stop_at_main : Option<"stop-at-user-entry", "m">,
-    Desc<"Stop at the user entry point when launching a process.">;
+  def process_launch_stop_at_user_entry : Option<"stop-at-user-entry", "m">,
+    Desc<"Stop at the user entry point when launching a process. For C based "
+    "languages this will be the 'main' function, but this might differ for "
+    "other languages.">;
   def process_launch_disable_aslr : Option<"disable-aslr", "A">, Arg<"Boolean">,
     Desc<"Set whether to disable address space layout randomization when launching a process.">;
   def process_launch_plugin : Option<"plugin", "P">, Arg<"Plugin">,

>From 0e4b149cdb4917abd624b4fb785fc110cf7b1c57 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jos=C3=A9=20L=2E=20Junior?= <jljuniorpb at gmail.com>
Date: Fri, 29 Sep 2023 11:33:59 -0300
Subject: [PATCH 8/9] use SetVector | change comments style

---
 .../Commands/CommandOptionsProcessLaunch.cpp  | 24 +++++++++++--------
 1 file changed, 14 insertions(+), 10 deletions(-)

diff --git a/lldb/source/Commands/CommandOptionsProcessLaunch.cpp b/lldb/source/Commands/CommandOptionsProcessLaunch.cpp
index a71ee5db8f2f27c..450bb8858d1fcbe 100644
--- a/lldb/source/Commands/CommandOptionsProcessLaunch.cpp
+++ b/lldb/source/Commands/CommandOptionsProcessLaunch.cpp
@@ -21,6 +21,7 @@
 #include "lldb/Target/Target.h"
 
 #include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SetVector.h"
 
 using namespace llvm;
 using namespace lldb;
@@ -46,7 +47,9 @@ Status CommandOptionsProcessLaunch::SetOptionValue(
     ModuleSP main_module_sp = target_sp->GetExecutableModule();
     FileSpecList shared_lib_filter;
     shared_lib_filter.Append(main_module_sp->GetFileSpec());
-    std::set<std::string> entryPointNamesSet;
+    llvm::SetVector<std::string, std::vector<std::string>,
+                    std::unordered_set<std::string>>
+        entryPointNamesSet;
     for (LanguageType lang_type : Language::GetSupportedLanguages()) {
       Language *lang = Language::FindPlugin(lang_type);
       if (lang) {
@@ -55,16 +58,17 @@ Status CommandOptionsProcessLaunch::SetOptionValue(
           entryPointNamesSet.insert(entryPointName);
       }
     }
-    std::vector<std::string> entryPointNames(entryPointNamesSet.begin(),
-                                             entryPointNamesSet.end());
     BreakpointSP bp_sp = target_sp->CreateBreakpoint(
-        /*containingModules=*/&shared_lib_filter,
-        /*containingSourceFiles=*/nullptr,
-        /*func_names=*/entryPointNames,
-        /*func_name_type_mask=*/eFunctionNameTypeFull,
-        /*language=*/eLanguageTypeUnknown,
-        /*offset=*/0, /*skip_prologue=*/eLazyBoolNo, /*internal=*/false,
-        /*hardware=*/false);
+        &shared_lib_filter,
+        nullptr, // containingSourceFiles
+        entryPointNamesSet.takeVector(),
+        eFunctionNameTypeFull, // func_name_type_mask
+        eLanguageTypeUnknown,  // language
+        0,                     // offset
+        eLazyBoolNo,           // skip_prologue
+        false,                 // internal
+        false                  // hardware
+    );
     if (!bp_sp)
       error.SetErrorString("Breakpoint creation failed.\n");
     bp_sp->SetOneShot(true);

>From 81eab79bb008fbd4ee6cf523c3df464b9ce683a8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jos=C3=A9=20L=2E=20Junior?= <jljuniorpb at gmail.com>
Date: Fri, 29 Sep 2023 14:31:16 -0300
Subject: [PATCH 9/9] replace const char* by StringRef | change if statements
 to return early

---
 lldb/include/lldb/Target/Language.h           |  2 +-
 .../Commands/CommandOptionsProcessLaunch.cpp  | 21 +++++++++++++------
 .../Language/CPlusPlus/CPlusPlusLanguage.h    |  2 +-
 .../Plugins/Language/ObjC/ObjCLanguage.h      |  2 +-
 .../ObjCPlusPlus/ObjCPlusPlusLanguage.h       |  2 +-
 5 files changed, 19 insertions(+), 10 deletions(-)

diff --git a/lldb/include/lldb/Target/Language.h b/lldb/include/lldb/Target/Language.h
index 943c7f0d3df8d65..cf781fc0e8dd5ee 100644
--- a/lldb/include/lldb/Target/Language.h
+++ b/lldb/include/lldb/Target/Language.h
@@ -168,7 +168,7 @@ class Language : public PluginInterface {
 
   // Implement this function to return the user-defined entry point name
   // for the language
-  virtual const char *GetUserEntryPointName() const { return nullptr; }
+  virtual llvm::StringRef GetUserEntryPointName() const { return {}; }
 
   virtual bool IsTopLevelFunction(Function &function);
 
diff --git a/lldb/source/Commands/CommandOptionsProcessLaunch.cpp b/lldb/source/Commands/CommandOptionsProcessLaunch.cpp
index 450bb8858d1fcbe..2645b7bdd8c4ae6 100644
--- a/lldb/source/Commands/CommandOptionsProcessLaunch.cpp
+++ b/lldb/source/Commands/CommandOptionsProcessLaunch.cpp
@@ -8,6 +8,7 @@
 
 #include "CommandOptionsProcessLaunch.h"
 
+#include "lldb/Core/Module.h"
 #include "lldb/Host/FileSystem.h"
 #include "lldb/Host/HostInfo.h"
 #include "lldb/Host/OptionParser.h"
@@ -15,11 +16,11 @@
 #include "lldb/Interpreter/CommandObject.h"
 #include "lldb/Interpreter/CommandOptionArgumentTable.h"
 #include "lldb/Interpreter/OptionArgParser.h"
+#include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Target/ExecutionContext.h"
 #include "lldb/Target/Language.h"
 #include "lldb/Target/Platform.h"
 #include "lldb/Target/Target.h"
-
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/SetVector.h"
 
@@ -52,11 +53,17 @@ Status CommandOptionsProcessLaunch::SetOptionValue(
         entryPointNamesSet;
     for (LanguageType lang_type : Language::GetSupportedLanguages()) {
       Language *lang = Language::FindPlugin(lang_type);
-      if (lang) {
-        std::string entryPointName = lang->GetUserEntryPointName();
-        if (!entryPointName.empty())
-          entryPointNamesSet.insert(entryPointName);
+      if (!lang) {
+        error.SetErrorString("Language not found\n");
+        break;
       }
+      std::string entryPointName = lang->GetUserEntryPointName().str();
+      if (!entryPointName.empty())
+        entryPointNamesSet.insert(entryPointName);
+    }
+    if (entryPointNamesSet.empty()) {
+      error.SetErrorString("No entry point name found\n");
+      break;
     }
     BreakpointSP bp_sp = target_sp->CreateBreakpoint(
         &shared_lib_filter,
@@ -69,8 +76,10 @@ Status CommandOptionsProcessLaunch::SetOptionValue(
         false,                 // internal
         false                  // hardware
     );
-    if (!bp_sp)
+    if (!bp_sp) {
       error.SetErrorString("Breakpoint creation failed.\n");
+      break;
+    }
     bp_sp->SetOneShot(true);
     break;
   }
diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h
index 648b6e2006b3473..bde34e710a44d85 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h
+++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h
@@ -103,7 +103,7 @@ class CPlusPlusLanguage : public Language {
     return lldb::eLanguageTypeC_plus_plus;
   }
 
-  const char *GetUserEntryPointName() const override { return "main"; }
+  llvm::StringRef GetUserEntryPointName() const override { return "main"; }
 
   std::unique_ptr<TypeScavenger> GetTypeScavenger() override;
   lldb::TypeCategoryImplSP GetFormatters() override;
diff --git a/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h b/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h
index f2ce8c050fc35ce..a50f4b036108d7a 100644
--- a/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h
+++ b/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h
@@ -127,7 +127,7 @@ class ObjCLanguage : public Language {
     return lldb::eLanguageTypeObjC;
   }
 
-  const char *GetUserEntryPointName() const override { return "main"; }
+  llvm::StringRef GetUserEntryPointName() const override { return "main"; }
 
   // Get all possible names for a method. Examples:
   // If method_name is "+[NSString(my_additions) myStringWithCString:]"
diff --git a/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h b/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h
index 177bb3517557fe4..1beab9348eb72e8 100644
--- a/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h
+++ b/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h
@@ -27,7 +27,7 @@ class ObjCPlusPlusLanguage : public Language {
     return lldb::eLanguageTypeObjC_plus_plus;
   }
 
-  const char *GetUserEntryPointName() const override { return "main"; }
+  llvm::StringRef GetUserEntryPointName() const override { return "main"; }
 
   llvm::StringRef GetNilReferenceSummaryString() override { return "nil"; }
 



More information about the lldb-commits mailing list