[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
Mon Oct 9 11:55:53 PDT 2023
https://github.com/junior-jl updated https://github.com/llvm/llvm-project/pull/67019
>From 5e03656813dfa9ff5985a9e1aa7a001872115500 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jos=C3=A9=20L=2E=20Junior?= <jljuniorpb at gmail.com>
Date: Tue, 3 Oct 2023 15:28:45 -0300
Subject: [PATCH] [lldb] add stop-at-user-entry option to process launch
[lldb] add stop-at-user-entry option to process launch
refactor CreateBreakpointAtUserEntry method
remove unecessary includes
---
lldb/include/lldb/Target/Language.h | 4 ++
lldb/include/lldb/Target/Target.h | 2 +
.../Commands/CommandOptionsProcessLaunch.cpp | 8 ++--
lldb/source/Commands/Options.td | 4 ++
.../Language/CPlusPlus/CPlusPlusLanguage.h | 2 +
.../Plugins/Language/ObjC/ObjCLanguage.h | 2 +
.../ObjCPlusPlus/ObjCPlusPlusLanguage.h | 2 +
lldb/source/Target/Target.cpp | 41 +++++++++++++++++++
.../command-process-launch-user-entry.test | 8 ++++
9 files changed, 70 insertions(+), 3 deletions(-)
create mode 100644 lldb/test/Shell/Commands/command-process-launch-user-entry.test
diff --git a/lldb/include/lldb/Target/Language.h b/lldb/include/lldb/Target/Language.h
index a6b9ccaf31b3c42..d53089ba4a59974 100644
--- a/lldb/include/lldb/Target/Language.h
+++ b/lldb/include/lldb/Target/Language.h
@@ -160,6 +160,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;
diff --git a/lldb/include/lldb/Target/Target.h b/lldb/include/lldb/Target/Target.h
index e9e531d0e12640a..8752b42a9518983 100644
--- a/lldb/include/lldb/Target/Target.h
+++ b/lldb/include/lldb/Target/Target.h
@@ -654,6 +654,8 @@ class Target : public std::enable_shared_from_this<Target>,
lldb::BreakpointSP GetBreakpointByID(lldb::break_id_t break_id);
+ lldb::BreakpointSP CreateBreakpointAtUserEntry(Status &error);
+
// Use this to create a file and line breakpoint to a given module or all
// module it is nullptr
lldb::BreakpointSP CreateBreakpoint(const FileSpecList *containingModules,
diff --git a/lldb/source/Commands/CommandOptionsProcessLaunch.cpp b/lldb/source/Commands/CommandOptionsProcessLaunch.cpp
index 85ad8ff5e07132c..b1c13d4df79e0ee 100644
--- a/lldb/source/Commands/CommandOptionsProcessLaunch.cpp
+++ b/lldb/source/Commands/CommandOptionsProcessLaunch.cpp
@@ -34,11 +34,15 @@ Status CommandOptionsProcessLaunch::SetOptionValue(
Status error;
const int short_option = g_process_launch_options[option_idx].short_option;
+ TargetSP target_sp =
+ execution_context ? execution_context->GetTargetSP() : TargetSP();
switch (short_option) {
case 's': // Stop at program entry point
launch_info.GetFlags().Set(eLaunchFlagStopAtEntry);
break;
-
+ case 'm': // Stop at user entry point
+ target_sp->CreateBreakpointAtUserEntry(error);
+ break;
case 'i': // STDIN for read only
{
FileAction action;
@@ -89,8 +93,6 @@ Status CommandOptionsProcessLaunch::SetOptionValue(
break;
case 'a': {
- TargetSP target_sp =
- execution_context ? execution_context->GetTargetSP() : TargetSP();
PlatformSP platform_sp =
target_sp ? target_sp->GetPlatform() : PlatformSP();
launch_info.GetArchitecture() =
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..623d481bf117f48 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;
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;
diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index f197b1b1aa097c3..eaf9e51a7e56a90 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -335,6 +335,47 @@ BreakpointSP Target::GetBreakpointByID(break_id_t break_id) {
return bp_sp;
}
+lldb::BreakpointSP
+lldb_private::Target::CreateBreakpointAtUserEntry(Status &error) {
+ ModuleSP main_module_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");
+ return lldb::BreakpointSP();
+ }
+ std::string entryPointName = lang->GetUserEntryPointName().str();
+ if (!entryPointName.empty())
+ entryPointNamesSet.insert(entryPointName);
+ }
+ if (entryPointNamesSet.empty()) {
+ error.SetErrorString("No entry point name found\n");
+ return lldb::BreakpointSP();
+ }
+ BreakpointSP bp_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");
+ return lldb::BreakpointSP();
+ }
+ bp_sp->SetOneShot(true);
+ return bp_sp;
+}
+
BreakpointSP Target::CreateSourceRegexBreakpoint(
const FileSpecList *containingModules,
const FileSpecList *source_file_spec_list,
diff --git a/lldb/test/Shell/Commands/command-process-launch-user-entry.test b/lldb/test/Shell/Commands/command-process-launch-user-entry.test
new file mode 100644
index 000000000000000..32ef710fe567439
--- /dev/null
+++ b/lldb/test/Shell/Commands/command-process-launch-user-entry.test
@@ -0,0 +1,8 @@
+# RUN: %clang_host -g %S/Inputs/main.c -o %t
+# RUN: %lldb %t -s %s -o exit | FileCheck %s
+
+process launch -m
+# CHECK-LABEL: process launch -m
+# CHECK: Process {{.*}} stopped
+# CHECK: stop reason = one-shot breakpoint 1
+# CHECK: frame #0: {{.*}}`main at main.c
\ No newline at end of file
More information about the lldb-commits
mailing list