mirror of
https://github.com/intel/llvm.git
synced 2026-01-20 10:58:11 +08:00
[lldb] Add more ways to find the .dwp file. (#81067)
When using split DWARF we can run into many different ways to store debug info: - lldb loads `<exe>` which contains skeleton DWARF and needs to find `<exe>.dwp` - lldb loads `<exe>` which is stripped but has .gnu_debuglink pointing to `<exe>.debug` with skeleton DWARF and needs to find `<exe>.dwp` - lldb loads `<exe>` which is stripped but has .gnu_debuglink pointing to `<exe>.debug` with skeleton DWARF and needs to find `<exe>.debug.dwp` - lldb loads `<exe>.debug` and needs to find `<exe>.dwp` Previously we only handled the first two cases. This patch adds support for the latter two.
This commit is contained in:
@@ -238,6 +238,10 @@ public:
|
||||
const_iterator begin() const { return m_files.begin(); }
|
||||
const_iterator end() const { return m_files.end(); }
|
||||
|
||||
llvm::iterator_range<const_iterator> files() const {
|
||||
return llvm::make_range(begin(), end());
|
||||
}
|
||||
|
||||
protected:
|
||||
collection m_files; ///< A collection of FileSpec objects.
|
||||
};
|
||||
|
||||
@@ -22,6 +22,7 @@ static constexpr Log::Category g_categories[] = {
|
||||
{{"map"},
|
||||
{"log insertions of object files into DWARF debug maps"},
|
||||
DWARFLog::DebugMap},
|
||||
{{"split"}, {"log split DWARF related activities"}, DWARFLog::SplitDwarf},
|
||||
};
|
||||
|
||||
static Log::Channel g_channel(g_categories, DWARFLog::DebugInfo);
|
||||
|
||||
@@ -20,6 +20,7 @@ enum class DWARFLog : Log::MaskType {
|
||||
DebugMap = Log::ChannelFlag<2>,
|
||||
Lookups = Log::ChannelFlag<3>,
|
||||
TypeCompletion = Log::ChannelFlag<4>,
|
||||
SplitDwarf = Log::ChannelFlag<5>,
|
||||
LLVM_MARK_AS_BITMASK_ENUM(TypeCompletion)
|
||||
};
|
||||
LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
|
||||
|
||||
@@ -4349,26 +4349,60 @@ SymbolFileDWARFDebugMap *SymbolFileDWARF::GetDebugMapSymfile() {
|
||||
|
||||
const std::shared_ptr<SymbolFileDWARFDwo> &SymbolFileDWARF::GetDwpSymbolFile() {
|
||||
llvm::call_once(m_dwp_symfile_once_flag, [this]() {
|
||||
// Create a list of files to try and append .dwp to.
|
||||
FileSpecList symfiles;
|
||||
// Append the module's object file path.
|
||||
const FileSpec module_fspec = m_objfile_sp->GetModule()->GetFileSpec();
|
||||
symfiles.Append(module_fspec);
|
||||
// Append the object file for this SymbolFile only if it is different from
|
||||
// the module's file path. Our main module could be "a.out", our symbol file
|
||||
// could be "a.debug" and our ".dwp" file might be "a.debug.dwp" instead of
|
||||
// "a.out.dwp".
|
||||
const FileSpec symfile_fspec(m_objfile_sp->GetFileSpec());
|
||||
if (symfile_fspec != module_fspec) {
|
||||
symfiles.Append(symfile_fspec);
|
||||
} else {
|
||||
// If we don't have a separate debug info file, then try stripping the
|
||||
// extension. The main module could be "a.debug" and the .dwp file could
|
||||
// be "a.dwp" instead of "a.debug.dwp".
|
||||
ConstString filename_no_ext =
|
||||
module_fspec.GetFileNameStrippingExtension();
|
||||
if (filename_no_ext != module_fspec.GetFilename()) {
|
||||
FileSpec module_spec_no_ext(module_fspec);
|
||||
module_spec_no_ext.SetFilename(filename_no_ext);
|
||||
symfiles.Append(module_spec_no_ext);
|
||||
}
|
||||
}
|
||||
Log *log = GetLog(DWARFLog::SplitDwarf);
|
||||
FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths();
|
||||
ModuleSpec module_spec;
|
||||
module_spec.GetFileSpec() = m_objfile_sp->GetFileSpec();
|
||||
module_spec.GetSymbolFileSpec() =
|
||||
FileSpec(m_objfile_sp->GetModule()->GetFileSpec().GetPath() + ".dwp");
|
||||
|
||||
module_spec.GetUUID() = m_objfile_sp->GetUUID();
|
||||
FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths();
|
||||
FileSpec dwp_filespec =
|
||||
PluginManager::LocateExecutableSymbolFile(module_spec, search_paths);
|
||||
if (FileSystem::Instance().Exists(dwp_filespec)) {
|
||||
DataBufferSP dwp_file_data_sp;
|
||||
lldb::offset_t dwp_file_data_offset = 0;
|
||||
ObjectFileSP dwp_obj_file = ObjectFile::FindPlugin(
|
||||
GetObjectFile()->GetModule(), &dwp_filespec, 0,
|
||||
FileSystem::Instance().GetByteSize(dwp_filespec), dwp_file_data_sp,
|
||||
dwp_file_data_offset);
|
||||
if (!dwp_obj_file)
|
||||
return;
|
||||
m_dwp_symfile = std::make_shared<SymbolFileDWARFDwo>(
|
||||
*this, dwp_obj_file, DIERef::k_file_index_mask);
|
||||
for (const auto &symfile : symfiles.files()) {
|
||||
module_spec.GetSymbolFileSpec() =
|
||||
FileSpec(symfile.GetPath() + ".dwp", symfile.GetPathStyle());
|
||||
LLDB_LOG(log, "Searching for DWP using: \"{0}\"",
|
||||
module_spec.GetSymbolFileSpec());
|
||||
FileSpec dwp_filespec =
|
||||
PluginManager::LocateExecutableSymbolFile(module_spec, search_paths);
|
||||
if (FileSystem::Instance().Exists(dwp_filespec)) {
|
||||
LLDB_LOG(log, "Found DWP file: \"{0}\"", dwp_filespec);
|
||||
DataBufferSP dwp_file_data_sp;
|
||||
lldb::offset_t dwp_file_data_offset = 0;
|
||||
ObjectFileSP dwp_obj_file = ObjectFile::FindPlugin(
|
||||
GetObjectFile()->GetModule(), &dwp_filespec, 0,
|
||||
FileSystem::Instance().GetByteSize(dwp_filespec), dwp_file_data_sp,
|
||||
dwp_file_data_offset);
|
||||
if (dwp_obj_file) {
|
||||
m_dwp_symfile = std::make_shared<SymbolFileDWARFDwo>(
|
||||
*this, dwp_obj_file, DIERef::k_file_index_mask);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!m_dwp_symfile) {
|
||||
LLDB_LOG(log, "Unable to locate for DWP file for: \"{0}\"",
|
||||
m_objfile_sp->GetModule()->GetFileSpec());
|
||||
}
|
||||
});
|
||||
return m_dwp_symfile;
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
// REQUIRES: lld
|
||||
|
||||
// Now test with DWARF5
|
||||
// RUN: %clang -target x86_64-pc-linux -gsplit-dwarf -gdwarf-5 -c %s -o %t.dwarf5.o
|
||||
// RUN: ld.lld %t.dwarf5.o -o %t.dwarf5
|
||||
// RUN: llvm-dwp %t.dwarf5.dwo -o %t.dwarf5.dwp
|
||||
// RUN: rm %t.dwarf5.dwo
|
||||
// RUN: llvm-objcopy --only-keep-debug %t.dwarf5 %t.dwarf5.debug
|
||||
// RUN: llvm-objcopy --strip-all --add-gnu-debuglink=%t.dwarf5.debug %t.dwarf5
|
||||
// RUN: %lldb %t.dwarf5 -o "target variable a" -b | FileCheck %s
|
||||
// RUN: %lldb \
|
||||
// RUN: -O "log enable dwarf split" \
|
||||
// RUN: -o "target variable a" \
|
||||
// RUN: -b %t.dwarf5 | FileCheck %s
|
||||
|
||||
// Run one time with the index cache enabled to populate the index cache. When
|
||||
// we populate the index cache we have to parse all of the DWARF debug info
|
||||
@@ -34,6 +38,31 @@
|
||||
// RUN: -o "statistics dump" \
|
||||
// RUN: %t.dwarf5 -b | FileCheck %s -check-prefix=CACHED
|
||||
|
||||
// Make sure that if we load the "%t.dwarf5.debug" file, that we can find and
|
||||
// load the .dwo file from the .dwp when it is "%t.dwarf5.dwp"
|
||||
// RUN: %lldb %t.dwarf5.debug -o "b main" -b | FileCheck %s -check-prefix=DEBUG
|
||||
|
||||
// Make sure that if we load the "%t.dwarf5" file, that we can find and
|
||||
// load the .dwo file from the .dwp when it is "%t.dwarf5.debug.dwp"
|
||||
// RUN: mv %t.dwarf5.dwp %t.dwarf5.debug.dwp
|
||||
// RUN: %lldb %t.dwarf5 -o "b main" -b | FileCheck %s -check-prefix=DEBUG
|
||||
|
||||
// Make sure that if we load the "%t.dwarf5.debug" file, that we can find and
|
||||
// load the .dwo file from the .dwp when it is "%t.dwarf5.debug.dwp"
|
||||
// RUN: %lldb %t.dwarf5.debug -o "b main" -b | FileCheck %s -check-prefix=DEBUG
|
||||
|
||||
// Make sure that if we remove the .dwp file we see an appropriate error.
|
||||
// RUN: rm %t.dwarf5.debug.dwp
|
||||
// RUN: %lldb \
|
||||
// RUN: -O "log enable dwarf split" \
|
||||
// RUN: -o "b main" \
|
||||
// RUN: -b %t.dwarf5 2>&1 | FileCheck %s -check-prefix=NODWP
|
||||
|
||||
// RUN: %lldb \
|
||||
// RUN: -O "log enable dwarf split" \
|
||||
// RUN: -o "b main" \
|
||||
// RUN: -b %t.dwarf5.debug 2>&1 | FileCheck %s -check-prefix=NODWP
|
||||
|
||||
// Now test with DWARF4
|
||||
// RUN: %clang -target x86_64-pc-linux -gsplit-dwarf -gdwarf-4 -c %s -o %t.dwarf4.o
|
||||
// RUN: ld.lld %t.dwarf4.o -o %t.dwarf4
|
||||
@@ -41,7 +70,10 @@
|
||||
// RUN: rm %t.dwarf4.dwo
|
||||
// RUN: llvm-objcopy --only-keep-debug %t.dwarf4 %t.dwarf4.debug
|
||||
// RUN: llvm-objcopy --strip-all --add-gnu-debuglink=%t.dwarf4.debug %t.dwarf4
|
||||
// RUN: %lldb %t.dwarf4 -o "target variable a" -b | FileCheck %s
|
||||
// RUN: %lldb \
|
||||
// RUN: -O "log enable dwarf split" \
|
||||
// RUN: -o "target variable a" \
|
||||
// RUN: -b %t.dwarf4 | FileCheck %s
|
||||
|
||||
// Run one time with the index cache enabled to populate the index cache. When
|
||||
// we populate the index cache we have to parse all of the DWARF debug info
|
||||
@@ -69,6 +101,46 @@
|
||||
// RUN: -o "statistics dump" \
|
||||
// RUN: %t.dwarf4 -b | FileCheck %s -check-prefix=CACHED
|
||||
|
||||
// Make sure that if we load the "%t.dwarf4.debug" file, that we can find and
|
||||
// load the .dwo file from the .dwp when it is "%t.dwarf4.dwp"
|
||||
// RUN: %lldb %t.dwarf4.debug -o "b main" -b | FileCheck %s -check-prefix=DEBUG
|
||||
|
||||
// Make sure that if we load the "%t.dwarf4" file, that we can find and
|
||||
// load the .dwo file from the .dwp when it is "%t.dwarf4.debug.dwp"
|
||||
// RUN: mv %t.dwarf4.dwp %t.dwarf4.debug.dwp
|
||||
// RUN: %lldb %t.dwarf4 -o "b main" -b | FileCheck %s -check-prefix=DEBUG
|
||||
|
||||
// Make sure that if we load the "%t.dwarf4.debug" file, that we can find and
|
||||
// load the .dwo file from the .dwp when it is "%t.dwarf4.debug.dwp"
|
||||
// RUN: %lldb %t.dwarf4.debug -o "b main" -b | FileCheck %s -check-prefix=DEBUG
|
||||
|
||||
// Make sure that if we remove the .dwp file we see an appropriate error.
|
||||
// RUN: rm %t.dwarf4.debug.dwp
|
||||
// RUN: %lldb \
|
||||
// RUN: -O "log enable dwarf split" \
|
||||
// RUN: -o "b main" \
|
||||
// RUN: -b %t.dwarf4 2>&1 | FileCheck %s -check-prefix=NODWP
|
||||
|
||||
// RUN: %lldb \
|
||||
// RUN: -O "log enable dwarf split" \
|
||||
// RUN: -o "b main" \
|
||||
// RUN: -b %t.dwarf4.debug 2>&1 | FileCheck %s -check-prefix=NODWP
|
||||
|
||||
// Test if we have a GNU build ID in our main executable and in our debug file,
|
||||
// and we have a .dwp file that doesn't, that we can still load our .dwp file.
|
||||
// RUN: %clang -target x86_64-pc-linux -gsplit-dwarf -gdwarf-5 -c %s -o %t.o
|
||||
// RUN: ld.lld %t.o --build-id=md5 -o %t
|
||||
// RUN: llvm-dwp %t.dwo -o %t.dwp
|
||||
// RUN: rm %t.dwo
|
||||
// RUN: llvm-objcopy --only-keep-debug %t %t.debug
|
||||
// RUN: llvm-objcopy --strip-all --add-gnu-debuglink=%t.debug %t
|
||||
// RUN: %lldb \
|
||||
// RUN: -O "log enable dwarf split" \
|
||||
// RUN: -o "target variable a" \
|
||||
// RUN: -b %t | FileCheck %s
|
||||
|
||||
// CHECK: Searching for DWP using:
|
||||
// CHECK: Found DWP file:
|
||||
// CHECK: (A) a = (x = 47)
|
||||
|
||||
// CACHE: script lldb.target.modules[0].FindTypes('::A').GetTypeAtIndex(0)
|
||||
@@ -83,6 +155,16 @@
|
||||
// CACHED-NEXT: }
|
||||
// CACHED: "totalDebugInfoIndexLoadedFromCache": 1
|
||||
|
||||
// Make sure debug information was loaded by verifying that the
|
||||
// DEBUG: Breakpoint 1: where = dwp-separate-debug-file.cpp.tmp.dwarf{{[45]}}{{(\.debug)?}}`main + {{[0-9]+}} at dwp-separate-debug-file.cpp:{{[0-9]+}}:{{[0-9]+}}, address = {{0x[0-9a-fA-F]+}}
|
||||
|
||||
// Make sure if we load the stripped binary or the debug info file with no .dwp
|
||||
// nor any .dwo files that we are not able to fine the .dwp or .dwo files.
|
||||
// NODWP: Searching for DWP using:
|
||||
// NODWP: Searching for DWP using:
|
||||
// NODWP: Unable to locate for DWP file for:
|
||||
// NODWP: unable to locate separate debug file (dwo, dwp). Debugging will be degraded.
|
||||
|
||||
struct A {
|
||||
int x = 47;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user