Skip to content

Commit 6fd515e

Browse files
committed
[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
1 parent 7a73da4 commit 6fd515e

File tree

9 files changed

+68
-3
lines changed

9 files changed

+68
-3
lines changed

lldb/include/lldb/Target/Language.h

+4
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,10 @@ class Language : public PluginInterface {
160160

161161
virtual lldb::LanguageType GetLanguageType() const = 0;
162162

163+
// Implement this function to return the user-defined entry point name
164+
// for the language.
165+
virtual llvm::StringRef GetUserEntryPointName() const { return {}; }
166+
163167
virtual bool IsTopLevelFunction(Function &function);
164168

165169
virtual bool IsSourceFile(llvm::StringRef file_path) const = 0;

lldb/include/lldb/Target/Target.h

+2
Original file line numberDiff line numberDiff line change
@@ -654,6 +654,8 @@ class Target : public std::enable_shared_from_this<Target>,
654654

655655
lldb::BreakpointSP GetBreakpointByID(lldb::break_id_t break_id);
656656

657+
lldb::BreakpointSP CreateBreakpointAtUserEntry(Status &error);
658+
657659
// Use this to create a file and line breakpoint to a given module or all
658660
// module it is nullptr
659661
lldb::BreakpointSP CreateBreakpoint(const FileSpecList *containingModules,

lldb/source/Commands/CommandOptionsProcessLaunch.cpp

+5-3
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,15 @@ Status CommandOptionsProcessLaunch::SetOptionValue(
3434
Status error;
3535
const int short_option = g_process_launch_options[option_idx].short_option;
3636

37+
TargetSP target_sp =
38+
execution_context ? execution_context->GetTargetSP() : TargetSP();
3739
switch (short_option) {
3840
case 's': // Stop at program entry point
3941
launch_info.GetFlags().Set(eLaunchFlagStopAtEntry);
4042
break;
41-
43+
case 'm': // Stop at user entry point
44+
target_sp->CreateBreakpointAtUserEntry(error);
45+
break;
4246
case 'i': // STDIN for read only
4347
{
4448
FileAction action;
@@ -89,8 +93,6 @@ Status CommandOptionsProcessLaunch::SetOptionValue(
8993
break;
9094

9195
case 'a': {
92-
TargetSP target_sp =
93-
execution_context ? execution_context->GetTargetSP() : TargetSP();
9496
PlatformSP platform_sp =
9597
target_sp ? target_sp->GetPlatform() : PlatformSP();
9698
launch_info.GetArchitecture() =

lldb/source/Commands/Options.td

+4
Original file line numberDiff line numberDiff line change
@@ -675,6 +675,10 @@ let Command = "platform shell" in {
675675
let Command = "process launch" in {
676676
def process_launch_stop_at_entry : Option<"stop-at-entry", "s">,
677677
Desc<"Stop at the entry point of the program when launching a process.">;
678+
def process_launch_stop_at_user_entry : Option<"stop-at-user-entry", "m">,
679+
Desc<"Stop at the user entry point when launching a process. For C based "
680+
"languages this will be the 'main' function, but this might differ for "
681+
"other languages.">;
678682
def process_launch_disable_aslr : Option<"disable-aslr", "A">, Arg<"Boolean">,
679683
Desc<"Set whether to disable address space layout randomization when launching a process.">;
680684
def process_launch_plugin : Option<"plugin", "P">, Arg<"Plugin">,

lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h

+2
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@ class CPlusPlusLanguage : public Language {
103103
return lldb::eLanguageTypeC_plus_plus;
104104
}
105105

106+
llvm::StringRef GetUserEntryPointName() const override { return "main"; }
107+
106108
std::unique_ptr<TypeScavenger> GetTypeScavenger() override;
107109
lldb::TypeCategoryImplSP GetFormatters() override;
108110

lldb/source/Plugins/Language/ObjC/ObjCLanguage.h

+2
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,8 @@ class ObjCLanguage : public Language {
127127
return lldb::eLanguageTypeObjC;
128128
}
129129

130+
llvm::StringRef GetUserEntryPointName() const override { return "main"; }
131+
130132
// Get all possible names for a method. Examples:
131133
// If method_name is "+[NSString(my_additions) myStringWithCString:]"
132134
// variant_names[0] => "+[NSString myStringWithCString:]"

lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h

+2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ class ObjCPlusPlusLanguage : public Language {
2727
return lldb::eLanguageTypeObjC_plus_plus;
2828
}
2929

30+
llvm::StringRef GetUserEntryPointName() const override { return "main"; }
31+
3032
llvm::StringRef GetNilReferenceSummaryString() override { return "nil"; }
3133

3234
bool IsSourceFile(llvm::StringRef file_path) const override;

lldb/source/Target/Target.cpp

+39
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,45 @@ BreakpointSP Target::GetBreakpointByID(break_id_t break_id) {
335335
return bp_sp;
336336
}
337337

338+
lldb::BreakpointSP
339+
lldb_private::Target::CreateBreakpointAtUserEntry(Status &error) {
340+
ModuleSP main_module_sp = GetExecutableModule();
341+
FileSpecList shared_lib_filter;
342+
shared_lib_filter.Append(main_module_sp->GetFileSpec());
343+
llvm::SetVector<std::string, std::vector<std::string>,
344+
std::unordered_set<std::string>>
345+
entryPointNamesSet;
346+
for (LanguageType lang_type : Language::GetSupportedLanguages()) {
347+
Language *lang = Language::FindPlugin(lang_type);
348+
if (!lang) {
349+
error.SetErrorString("Language not found\n");
350+
return lldb::BreakpointSP();
351+
}
352+
std::string entryPointName = lang->GetUserEntryPointName().str();
353+
if (!entryPointName.empty())
354+
entryPointNamesSet.insert(entryPointName);
355+
}
356+
if (entryPointNamesSet.empty()) {
357+
error.SetErrorString("No entry point name found\n");
358+
return lldb::BreakpointSP();
359+
}
360+
BreakpointSP bp_sp = CreateBreakpoint(
361+
&shared_lib_filter,
362+
/*containingSourceFiles=*/nullptr, entryPointNamesSet.takeVector(),
363+
/*func_name_type_mask=*/eFunctionNameTypeFull,
364+
/*language=*/eLanguageTypeUnknown,
365+
/*offset=*/0,
366+
/*skip_prologue=*/eLazyBoolNo,
367+
/*internal=*/false,
368+
/*hardware=*/false);
369+
if (!bp_sp) {
370+
error.SetErrorString("Breakpoint creation failed.\n");
371+
return lldb::BreakpointSP();
372+
}
373+
bp_sp->SetOneShot(true);
374+
return bp_sp;
375+
}
376+
338377
BreakpointSP Target::CreateSourceRegexBreakpoint(
339378
const FileSpecList *containingModules,
340379
const FileSpecList *source_file_spec_list,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# RUN: %clang_host -g %S/Inputs/main.c -o %t
2+
# RUN: %lldb %t -s %s -o exit | FileCheck %s
3+
4+
process launch -m
5+
# CHECK-LABEL: process launch -m
6+
# CHECK: Process {{.*}} stopped
7+
# CHECK: stop reason = one-shot breakpoint 1
8+
# CHECK: frame #0: {{.*}}`main at main.c

0 commit comments

Comments
 (0)