Skip to content

Commit e77ac42

Browse files
author
Kevin Frei
authored
[lldb][debuginfod] Fix the DebugInfoD PR that caused issues when working with stripped binaries (#99362)
@walter-erquinigo found the the [PR with testing and a fix for DebugInfoD](#98344) caused an issue when working with stripped binaries. The issue is that when you're working with split-dwarf, there are *3* possible files: The stripped binary the user is debugging, the "only-keep-debug" *or* unstripped binary, plus the `.dwp` file. The debuginfod plugin should provide the unstripped/OKD binary. However, if the debuginfod plugin fails, the default symbol locator plugin will just return the stripped binary, which doesn't help. So, to address that, the SymbolVendorELF code checks to see if the SymbolLocator's ExecutableObjectFile request returned the same file, and bails if that's the case. You can see the specific diff as the second commit in the PR. I'm investigating adding a test: I can't quite get a simple repro, and I'm unwilling to make any additional changes to Makefile.rules to this diff, for Pavlovian reasons.
1 parent 3983bf6 commit e77ac42

File tree

13 files changed

+549
-21
lines changed

13 files changed

+549
-21
lines changed

lldb/include/lldb/Host/Config.h.cmake

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333

3434
#cmakedefine01 LLDB_ENABLE_LZMA
3535

36+
#cmakedefine01 LLVM_ENABLE_CURL
37+
3638
#cmakedefine01 LLDB_ENABLE_CURSES
3739

3840
#cmakedefine01 CURSES_HAVE_NCURSES_CURSES_H

lldb/packages/Python/lldbsuite/test/decorators.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1053,6 +1053,10 @@ def _get_bool_config_skip_if_decorator(key):
10531053
return unittest.skipIf(not have, "requires " + key)
10541054

10551055

1056+
def skipIfCurlSupportMissing(func):
1057+
return _get_bool_config_skip_if_decorator("curl")(func)
1058+
1059+
10561060
def skipIfCursesSupportMissing(func):
10571061
return _get_bool_config_skip_if_decorator("curses")(func)
10581062

lldb/packages/Python/lldbsuite/test/make/Makefile.rules

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,12 @@ else
202202
ifeq "$(SPLIT_DEBUG_SYMBOLS)" "YES"
203203
DSYM = $(EXE).debug
204204
endif
205+
206+
ifeq "$(MAKE_DWP)" "YES"
207+
MAKE_DWO := YES
208+
DWP_NAME = $(EXE).dwp
209+
DYLIB_DWP_NAME = $(DYLIB_NAME).dwp
210+
endif
205211
endif
206212

207213
LIMIT_DEBUG_INFO_FLAGS =
@@ -347,6 +353,17 @@ ifneq "$(OS)" "Darwin"
347353

348354
OBJCOPY ?= $(call replace_cc_with,objcopy)
349355
ARCHIVER ?= $(call replace_cc_with,ar)
356+
# Look for llvm-dwp or gnu dwp
357+
DWP ?= $(call replace_cc_with,llvm-dwp)
358+
ifeq ($(wildcard $(DWP)),)
359+
DWP = $(call replace_cc_with,dwp)
360+
ifeq ($(wildcard $(DWP)),)
361+
DWP = $(shell command -v llvm-dwp 2> /dev/null)
362+
ifeq ($(wildcard $(DWP)),)
363+
DWP = $(shell command -v dwp 2> /dev/null)
364+
endif
365+
endif
366+
endif
350367
override AR = $(ARCHIVER)
351368
endif
352369

@@ -526,6 +543,10 @@ ifneq "$(CXX)" ""
526543
endif
527544
endif
528545

546+
ifeq "$(GEN_GNU_BUILD_ID)" "YES"
547+
LDFLAGS += -Wl,--build-id
548+
endif
549+
529550
#----------------------------------------------------------------------
530551
# DYLIB_ONLY variable can be used to skip the building of a.out.
531552
# See the sections below regarding dSYM file as well as the building of
@@ -564,11 +585,18 @@ else
564585
endif
565586
else
566587
ifeq "$(SPLIT_DEBUG_SYMBOLS)" "YES"
588+
ifeq "$(SAVE_FULL_DEBUG_BINARY)" "YES"
589+
cp "$(EXE)" "$(EXE).unstripped"
590+
endif
567591
$(OBJCOPY) --only-keep-debug "$(EXE)" "$(DSYM)"
568592
$(OBJCOPY) --strip-debug --add-gnu-debuglink="$(DSYM)" "$(EXE)" "$(EXE)"
569593
endif
594+
ifeq "$(MAKE_DWP)" "YES"
595+
$(DWP) -o "$(DWP_NAME)" $(DWOS)
596+
endif
570597
endif
571598

599+
572600
#----------------------------------------------------------------------
573601
# Make the dylib
574602
#----------------------------------------------------------------------
@@ -609,9 +637,15 @@ endif
609637
else
610638
$(LD) $(DYLIB_OBJECTS) $(LDFLAGS) -shared -o "$(DYLIB_FILENAME)"
611639
ifeq "$(SPLIT_DEBUG_SYMBOLS)" "YES"
640+
ifeq "$(SAVE_FULL_DEBUG_BINARY)" "YES"
641+
cp "$(DYLIB_FILENAME)" "$(DYLIB_FILENAME).unstripped"
642+
endif
612643
$(OBJCOPY) --only-keep-debug "$(DYLIB_FILENAME)" "$(DYLIB_FILENAME).debug"
613644
$(OBJCOPY) --strip-debug --add-gnu-debuglink="$(DYLIB_FILENAME).debug" "$(DYLIB_FILENAME)" "$(DYLIB_FILENAME)"
614645
endif
646+
ifeq "$(MAKE_DWP)" "YES"
647+
$(DWP) -o $(DYLIB_DWP_FILE) $(DYLIB_DWOS)
648+
endif
615649
endif
616650

617651
#----------------------------------------------------------------------

lldb/source/API/SBDebugger.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -775,6 +775,9 @@ SBStructuredData SBDebugger::GetBuildConfiguration() {
775775
AddBoolConfigEntry(
776776
*config_up, "xml", XMLDocument::XMLEnabled(),
777777
"A boolean value that indicates if XML support is enabled in LLDB");
778+
AddBoolConfigEntry(
779+
*config_up, "curl", LLVM_ENABLE_CURL,
780+
"A boolean value that indicates if CURL support is enabled in LLDB");
778781
AddBoolConfigEntry(
779782
*config_up, "curses", LLDB_ENABLE_CURSES,
780783
"A boolean value that indicates if curses support is enabled in LLDB");
@@ -1724,20 +1727,20 @@ SBDebugger::LoadTraceFromFile(SBError &error,
17241727

17251728
void SBDebugger::RequestInterrupt() {
17261729
LLDB_INSTRUMENT_VA(this);
1727-
1730+
17281731
if (m_opaque_sp)
1729-
m_opaque_sp->RequestInterrupt();
1732+
m_opaque_sp->RequestInterrupt();
17301733
}
17311734
void SBDebugger::CancelInterruptRequest() {
17321735
LLDB_INSTRUMENT_VA(this);
1733-
1736+
17341737
if (m_opaque_sp)
1735-
m_opaque_sp->CancelInterruptRequest();
1738+
m_opaque_sp->CancelInterruptRequest();
17361739
}
17371740

17381741
bool SBDebugger::InterruptRequested() {
17391742
LLDB_INSTRUMENT_VA(this);
1740-
1743+
17411744
if (m_opaque_sp)
17421745
return m_opaque_sp->InterruptRequested();
17431746
return false;

lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4331,26 +4331,38 @@ const std::shared_ptr<SymbolFileDWARFDwo> &SymbolFileDWARF::GetDwpSymbolFile() {
43314331
FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths();
43324332
ModuleSpec module_spec;
43334333
module_spec.GetFileSpec() = m_objfile_sp->GetFileSpec();
4334+
FileSpec dwp_filespec;
43344335
for (const auto &symfile : symfiles.files()) {
43354336
module_spec.GetSymbolFileSpec() =
43364337
FileSpec(symfile.GetPath() + ".dwp", symfile.GetPathStyle());
43374338
LLDB_LOG(log, "Searching for DWP using: \"{0}\"",
43384339
module_spec.GetSymbolFileSpec());
4339-
FileSpec dwp_filespec =
4340+
dwp_filespec =
43404341
PluginManager::LocateExecutableSymbolFile(module_spec, search_paths);
43414342
if (FileSystem::Instance().Exists(dwp_filespec)) {
4342-
LLDB_LOG(log, "Found DWP file: \"{0}\"", dwp_filespec);
4343-
DataBufferSP dwp_file_data_sp;
4344-
lldb::offset_t dwp_file_data_offset = 0;
4345-
ObjectFileSP dwp_obj_file = ObjectFile::FindPlugin(
4346-
GetObjectFile()->GetModule(), &dwp_filespec, 0,
4347-
FileSystem::Instance().GetByteSize(dwp_filespec), dwp_file_data_sp,
4348-
dwp_file_data_offset);
4349-
if (dwp_obj_file) {
4350-
m_dwp_symfile = std::make_shared<SymbolFileDWARFDwo>(
4351-
*this, dwp_obj_file, DIERef::k_file_index_mask);
4352-
break;
4353-
}
4343+
break;
4344+
}
4345+
}
4346+
if (!FileSystem::Instance().Exists(dwp_filespec)) {
4347+
LLDB_LOG(log, "No DWP file found locally");
4348+
// Fill in the UUID for the module we're trying to match for, so we can
4349+
// find the correct DWP file, as the Debuginfod plugin uses *only* this
4350+
// data to correctly match the DWP file with the binary.
4351+
module_spec.GetUUID() = m_objfile_sp->GetUUID();
4352+
dwp_filespec =
4353+
PluginManager::LocateExecutableSymbolFile(module_spec, search_paths);
4354+
}
4355+
if (FileSystem::Instance().Exists(dwp_filespec)) {
4356+
LLDB_LOG(log, "Found DWP file: \"{0}\"", dwp_filespec);
4357+
DataBufferSP dwp_file_data_sp;
4358+
lldb::offset_t dwp_file_data_offset = 0;
4359+
ObjectFileSP dwp_obj_file = ObjectFile::FindPlugin(
4360+
GetObjectFile()->GetModule(), &dwp_filespec, 0,
4361+
FileSystem::Instance().GetByteSize(dwp_filespec), dwp_file_data_sp,
4362+
dwp_file_data_offset);
4363+
if (dwp_obj_file) {
4364+
m_dwp_symfile = std::make_shared<SymbolFileDWARFDwo>(
4365+
*this, dwp_obj_file, DIERef::k_file_index_mask);
43544366
}
43554367
}
43564368
if (!m_dwp_symfile) {

lldb/source/Plugins/SymbolLocator/CMakeLists.txt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
1+
# Order matters here: the first symbol locator prevents further searching.
2+
# For DWARF binaries that are both stripped and split, the Default plugin
3+
# will return the stripped binary when asked for the ObjectFile, which then
4+
# prevents an unstripped binary from being requested from the Debuginfod
5+
# provider.
6+
add_subdirectory(Debuginfod)
17
add_subdirectory(Default)
28
if (CMAKE_SYSTEM_NAME MATCHES "Darwin")
39
add_subdirectory(DebugSymbols)
410
endif()
5-
add_subdirectory(Debuginfod)

lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,24 @@ llvm::StringRef SymbolVendorELF::GetPluginDescriptionStatic() {
4444
"executables.";
4545
}
4646

47+
// If this is needed elsewhere, it can be exported/moved.
48+
static bool IsDwpSymbolFile(const lldb::ModuleSP &module_sp,
49+
const FileSpec &file_spec) {
50+
DataBufferSP dwp_file_data_sp;
51+
lldb::offset_t dwp_file_data_offset = 0;
52+
// Try to create an ObjectFile from the file_spec.
53+
ObjectFileSP dwp_obj_file = ObjectFile::FindPlugin(
54+
module_sp, &file_spec, 0, FileSystem::Instance().GetByteSize(file_spec),
55+
dwp_file_data_sp, dwp_file_data_offset);
56+
// The presence of a debug_cu_index section is the key identifying feature of
57+
// a DWP file. Make sure we don't fill in the section list on dwp_obj_file
58+
// (by calling GetSectionList(false)) as this function could be called before
59+
// we may have all the symbol files collected and available.
60+
return dwp_obj_file && ObjectFileELF::classof(dwp_obj_file.get()) &&
61+
dwp_obj_file->GetSectionList(false)->FindSectionByType(
62+
eSectionTypeDWARFDebugCuIndex, false);
63+
}
64+
4765
// CreateInstance
4866
//
4967
// Platforms can register a callback to use when creating symbol vendors to
@@ -87,8 +105,20 @@ SymbolVendorELF::CreateInstance(const lldb::ModuleSP &module_sp,
87105
FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths();
88106
FileSpec dsym_fspec =
89107
PluginManager::LocateExecutableSymbolFile(module_spec, search_paths);
90-
if (!dsym_fspec)
91-
return nullptr;
108+
if (!dsym_fspec || IsDwpSymbolFile(module_sp, dsym_fspec)) {
109+
// If we have a stripped binary or if we have a DWP file, SymbolLocator
110+
// plugins may be able to give us an unstripped binary or an
111+
// 'only-keep-debug' stripped file.
112+
ModuleSpec unstripped_spec =
113+
PluginManager::LocateExecutableObjectFile(module_spec);
114+
if (!unstripped_spec)
115+
return nullptr;
116+
// The default SymbolLocator plugin returns the original binary if no other
117+
// plugin finds something better.
118+
if (unstripped_spec.GetFileSpec() == module_spec.GetFileSpec())
119+
return nullptr;
120+
dsym_fspec = unstripped_spec.GetFileSpec();
121+
}
92122

93123
DataBufferSP dsym_file_data_sp;
94124
lldb::offset_t dsym_file_data_offset = 0;
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
C_SOURCES := main.c
2+
3+
# For normal (non DWP) Debuginfod tests, we need:
4+
5+
# * The full binary: a.out.unstripped
6+
# Produced by Makefile.rules with SAVE_FULL_DEBUG_BINARY set to YES and
7+
# SPLIT_DEBUG_SYMBOLS set to YES
8+
9+
# * The stripped binary (a.out)
10+
# Produced by Makefile.rules with SPLIT_DEBUG_SYMBOLS set to YES
11+
12+
# * The 'only-keep-debug' binary (a.out.debug)
13+
# Produced below
14+
15+
SPLIT_DEBUG_SYMBOLS := YES
16+
SAVE_FULL_DEBUG_BINARY := YES
17+
GEN_GNU_BUILD_ID := YES
18+
19+
include Makefile.rules

0 commit comments

Comments
 (0)