https://github.com/junior-jl updated https://github.com/llvm/llvm-project/pull/67019
From 6de148adcdd1eedea7e23b4e267c6f42bb68bc45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20L=2E=20Junior?= <jljunio...@gmail.com> Date: Tue, 3 Oct 2023 15:28:45 -0300 Subject: [PATCH] [lldb] add stop-at-user-entry option to process launch --- lldb/include/lldb/Target/Language.h | 4 ++ lldb/include/lldb/Target/Target.h | 2 + .../Commands/CommandOptionsProcessLaunch.cpp | 13 +++++- 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 | 42 +++++++++++++++++++ .../command-process-launch-user-entry.test | 8 ++++ 9 files changed, 77 insertions(+), 2 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..82a343ee03fb516 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(); + // 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..3055e4ca45bd230 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,13 @@ 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(); + target_sp->CreateBreakpointAtUserEntry(); + 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..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..013d72bda6308be 100644 --- a/lldb/source/Target/Target.cpp +++ b/lldb/source/Target/Target.cpp @@ -335,6 +335,48 @@ BreakpointSP Target::GetBreakpointByID(break_id_t break_id) { return bp_sp; } +lldb::BreakpointSP lldb_private::Target::CreateBreakpointAtUserEntry() { + TargetSP target_sp = shared_from_this(); + Status error; + 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"); + 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 = + 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"); + 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 _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits