[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:48:25 PDT 2023


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

>From c2396253b9584af9eabe1e67ed922f5f5f0e879c 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] [lldb] add stop-at-user-entry option to process launch

[lldb] add command start

[lldb] add stop-at-main option to process launch

Revert "[lldb] add command start"

This reverts commit 11270775865a8415e00b4d899703f84717344967.

[lldb] remove shell modification | make bp one-shot

add GetUserEntryPointName method | changed bp creating method

use clang-format

change option description | using set for entrypoint names

use SetVector | change comments style

replace const char* by StringRef | change if statements to return early
---
 lldb/include/lldb/Target/Language.h           | 20 ++++++--
 .../Commands/CommandOptionsProcessLaunch.cpp  | 48 ++++++++++++++++++-
 lldb/source/Commands/Options.td               |  4 ++
 .../Language/CPlusPlus/CPlusPlusLanguage.h    |  6 ++-
 .../Plugins/Language/ObjC/ObjCLanguage.h      |  2 +
 .../ObjCPlusPlus/ObjCPlusPlusLanguage.h       |  2 +
 6 files changed, 73 insertions(+), 9 deletions(-)

diff --git a/lldb/include/lldb/Target/Language.h b/lldb/include/lldb/Target/Language.h
index a6b9ccaf31b3c42..cf781fc0e8dd5ee 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 llvm::StringRef GetUserEntryPointName() const { return {}; }
+
   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 85ad8ff5e07132c..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,13 @@
 #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"
 
 using namespace llvm;
 using namespace lldb;
@@ -38,7 +41,48 @@ Status CommandOptionsProcessLaunch::SetOptionValue(
   case 's': // Stop at program entry point
     launch_info.GetFlags().Set(eLaunchFlagStopAtEntry);
     break;
-
+  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());
+    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) {
+        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,
+        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");
+      break;
+    }
+    bp_sp->SetOneShot(true);
+    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..dd4cf5c4dc043e7 100644
--- a/lldb/source/Commands/Options.td
+++ b/lldb/source/Commands/Options.td
@@ -675,6 +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_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">,
diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h
index 7712a60b7795951..bde34e710a44d85 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;
   }
 
+  llvm::StringRef GetUserEntryPointName() const override { return "main"; }
+
   std::unique_ptr<TypeScavenger> GetTypeScavenger() override;
   lldb::TypeCategoryImplSP GetFormatters() override;
 
@@ -129,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/ObjC/ObjCLanguage.h b/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h
index bb8057846bb7c30..a50f4b036108d7a 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;
   }
 
+  llvm::StringRef 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..1beab9348eb72e8 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;
   }
 
+  llvm::StringRef GetUserEntryPointName() const override { return "main"; }
+
   llvm::StringRef GetNilReferenceSummaryString() override { return "nil"; }
 
   bool IsSourceFile(llvm::StringRef file_path) const override;



More information about the lldb-commits mailing list