Skip to content

Commit 6d939a6

Browse files
kevinfreiKevin Frei
andauthored
DebugInfoD tests + fixing issues exposed by tests (#85693)
Finally getting back to Debuginfod tests: I've migrated the tests in my [earlier PR](#79181) from shell to API (at @JDevlieghere's suggestion) and addressed a couple issues that came about during testing. The tests first test the "normal" situation (no DebugInfoD involvement, just normal debug files sitting around), then the "no debug info" situation (to make sure the test is seeing failure properly), then it tests to validate that when Debuginfod returns the symbols, things work properly. This is duplicated for DWP/split-dwarf scenarios. --------- Co-authored-by: Kevin Frei <[email protected]>
1 parent 85ccfb5 commit 6d939a6

File tree

10 files changed

+537
-17
lines changed

10 files changed

+537
-17
lines changed

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

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ LLDB_BASE_DIR := $(THIS_FILE_DIR)/../../../../../
5151
#
5252
# GNUWin32 uname gives "windows32" or "server version windows32" while
5353
# some versions of MSYS uname return "MSYS_NT*", but most environments
54-
# standardize on "Windows_NT", so we'll make it consistent here.
54+
# standardize on "Windows_NT", so we'll make it consistent here.
5555
# When running tests from Visual Studio, the environment variable isn't
5656
# inherited all the way down to the process spawned for make.
5757
#----------------------------------------------------------------------
@@ -210,6 +210,12 @@ else
210210
ifeq "$(SPLIT_DEBUG_SYMBOLS)" "YES"
211211
DSYM = $(EXE).debug
212212
endif
213+
214+
ifeq "$(MAKE_DWP)" "YES"
215+
MAKE_DWO := YES
216+
DWP_NAME = $(EXE).dwp
217+
DYLIB_DWP_NAME = $(DYLIB_NAME).dwp
218+
endif
213219
endif
214220

215221
LIMIT_DEBUG_INFO_FLAGS =
@@ -357,6 +363,7 @@ ifneq "$(OS)" "Darwin"
357363

358364
OBJCOPY ?= $(call replace_cc_with,objcopy)
359365
ARCHIVER ?= $(call replace_cc_with,ar)
366+
DWP ?= $(call replace_cc_with,dwp)
360367
override AR = $(ARCHIVER)
361368
endif
362369

@@ -527,6 +534,10 @@ ifneq "$(CXX)" ""
527534
endif
528535
endif
529536

537+
ifeq "$(GEN_GNU_BUILD_ID)" "YES"
538+
LDFLAGS += -Wl,--build-id
539+
endif
540+
530541
#----------------------------------------------------------------------
531542
# DYLIB_ONLY variable can be used to skip the building of a.out.
532543
# See the sections below regarding dSYM file as well as the building of
@@ -565,11 +576,25 @@ else
565576
endif
566577
else
567578
ifeq "$(SPLIT_DEBUG_SYMBOLS)" "YES"
579+
ifeq "$(SAVE_FULL_DEBUG_BINARY)" "YES"
580+
cp "$(EXE)" "$(EXE).full"
581+
endif
568582
$(OBJCOPY) --only-keep-debug "$(EXE)" "$(DSYM)"
569583
$(OBJCOPY) --strip-debug --add-gnu-debuglink="$(DSYM)" "$(EXE)" "$(EXE)"
570584
endif
585+
ifeq "$(MAKE_DWP)" "YES"
586+
$(DWP) -o "$(DWP_NAME)" $(DWOS)
587+
endif
571588
endif
572589

590+
591+
#----------------------------------------------------------------------
592+
# Support emitting the content of the GNU build-id into a file
593+
# This needs to be used in conjunction with GEN_GNU_BUILD_ID := YES
594+
#----------------------------------------------------------------------
595+
$(EXE).uuid : $(EXE)
596+
$(OBJCOPY) --dump-section=.note.gnu.build-id=$@ $<
597+
573598
#----------------------------------------------------------------------
574599
# Make the dylib
575600
#----------------------------------------------------------------------
@@ -610,9 +635,15 @@ endif
610635
else
611636
$(LD) $(DYLIB_OBJECTS) $(LDFLAGS) -shared -o "$(DYLIB_FILENAME)"
612637
ifeq "$(SPLIT_DEBUG_SYMBOLS)" "YES"
638+
ifeq "$(SAVE_FULL_DEBUG_BINARY)" "YES"
639+
cp "$(DYLIB_FILENAME)" "$(DYLIB_FILENAME).full"
640+
endif
613641
$(OBJCOPY) --only-keep-debug "$(DYLIB_FILENAME)" "$(DYLIB_FILENAME).debug"
614642
$(OBJCOPY) --strip-debug --add-gnu-debuglink="$(DYLIB_FILENAME).debug" "$(DYLIB_FILENAME)" "$(DYLIB_FILENAME)"
615643
endif
644+
ifeq "$(MAKE_DWP)" "YES"
645+
$(DWP) -o $(DYLIB_DWP_FILE) $(DYLIB_DWOS)
646+
endif
616647
endif
617648

618649
#----------------------------------------------------------------------

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

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4377,26 +4377,38 @@ const std::shared_ptr<SymbolFileDWARFDwo> &SymbolFileDWARF::GetDwpSymbolFile() {
43774377
FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths();
43784378
ModuleSpec module_spec;
43794379
module_spec.GetFileSpec() = m_objfile_sp->GetFileSpec();
4380+
FileSpec dwp_filespec;
43804381
for (const auto &symfile : symfiles.files()) {
43814382
module_spec.GetSymbolFileSpec() =
43824383
FileSpec(symfile.GetPath() + ".dwp", symfile.GetPathStyle());
43834384
LLDB_LOG(log, "Searching for DWP using: \"{0}\"",
43844385
module_spec.GetSymbolFileSpec());
4385-
FileSpec dwp_filespec =
4386+
dwp_filespec =
43864387
PluginManager::LocateExecutableSymbolFile(module_spec, search_paths);
43874388
if (FileSystem::Instance().Exists(dwp_filespec)) {
4388-
LLDB_LOG(log, "Found DWP file: \"{0}\"", dwp_filespec);
4389-
DataBufferSP dwp_file_data_sp;
4390-
lldb::offset_t dwp_file_data_offset = 0;
4391-
ObjectFileSP dwp_obj_file = ObjectFile::FindPlugin(
4392-
GetObjectFile()->GetModule(), &dwp_filespec, 0,
4393-
FileSystem::Instance().GetByteSize(dwp_filespec), dwp_file_data_sp,
4394-
dwp_file_data_offset);
4395-
if (dwp_obj_file) {
4396-
m_dwp_symfile = std::make_shared<SymbolFileDWARFDwo>(
4397-
*this, dwp_obj_file, DIERef::k_file_index_mask);
4398-
break;
4399-
}
4389+
break;
4390+
}
4391+
}
4392+
if (!FileSystem::Instance().Exists(dwp_filespec)) {
4393+
LLDB_LOG(log, "No DWP file found locally");
4394+
// Fill in the UUID for the module we're trying to match for, so we can
4395+
// find the correct DWP file, as the Debuginfod plugin uses *only* this
4396+
// data to correctly match the DWP file with the binary.
4397+
module_spec.GetUUID() = m_objfile_sp->GetUUID();
4398+
dwp_filespec =
4399+
PluginManager::LocateExecutableSymbolFile(module_spec, search_paths);
4400+
}
4401+
if (FileSystem::Instance().Exists(dwp_filespec)) {
4402+
LLDB_LOG(log, "Found DWP file: \"{0}\"", dwp_filespec);
4403+
DataBufferSP dwp_file_data_sp;
4404+
lldb::offset_t dwp_file_data_offset = 0;
4405+
ObjectFileSP dwp_obj_file = ObjectFile::FindPlugin(
4406+
GetObjectFile()->GetModule(), &dwp_filespec, 0,
4407+
FileSystem::Instance().GetByteSize(dwp_filespec), dwp_file_data_sp,
4408+
dwp_file_data_offset);
4409+
if (dwp_obj_file) {
4410+
m_dwp_symfile = std::make_shared<SymbolFileDWARFDwo>(
4411+
*this, dwp_obj_file, DIERef::k_file_index_mask);
44004412
}
44014413
}
44024414
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: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,25 @@ 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+
if (!ObjectFileELF::classof(dwp_obj_file.get()))
57+
return false;
58+
// The presence of a debug_cu_index section is the key identifying feature of
59+
// a DWP file. Make sure we don't fill in the section list on dwp_obj_file
60+
// (by calling GetSectionList(false)) as this is invoked before we may have
61+
// all the symbol files collected and available.
62+
return dwp_obj_file && dwp_obj_file->GetSectionList(false)->FindSectionByType(
63+
eSectionTypeDWARFDebugCuIndex, false);
64+
}
65+
4766
// CreateInstance
4867
//
4968
// Platforms can register a callback to use when creating symbol vendors to
@@ -87,8 +106,15 @@ SymbolVendorELF::CreateInstance(const lldb::ModuleSP &module_sp,
87106
FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths();
88107
FileSpec dsym_fspec =
89108
PluginManager::LocateExecutableSymbolFile(module_spec, search_paths);
90-
if (!dsym_fspec)
91-
return nullptr;
109+
if (!dsym_fspec || IsDwpSymbolFile(module_sp, dsym_fspec)) {
110+
// If we have a stripped binary or if we got a DWP file, we should prefer
111+
// symbols in the executable acquired through a plugin.
112+
ModuleSpec unstripped_spec =
113+
PluginManager::LocateExecutableObjectFile(module_spec);
114+
if (!unstripped_spec)
115+
return nullptr;
116+
dsym_fspec = unstripped_spec.GetFileSpec();
117+
}
92118

93119
DataBufferSP dsym_file_data_sp;
94120
lldb::offset_t dsym_file_data_offset = 0;
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
C_SOURCES := main.c
2+
3+
# For normal (non DWP) Debuginfod tests, we need:
4+
5+
# * The "full" binary: a.out.debug
6+
# Produced by Makefile.rules with KEEP_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.dbg)
13+
# Produced below
14+
15+
# * The .uuid file (for a little easier testing code)
16+
# Produced below
17+
18+
# Don't strip the debug info from a.out:
19+
SPLIT_DEBUG_SYMBOLS := YES
20+
SAVE_FULL_DEBUG_BINARY := YES
21+
GEN_GNU_BUILD_ID := YES
22+
23+
all: a.out.uuid a.out
24+
25+
include Makefile.rules

0 commit comments

Comments
 (0)