Author: Adrian McCarthy Date: 2020-08-11T13:44:14-07:00 New Revision: 479f5bfdb02b191f03b3de1a7c3d5a5098b3fcaf
URL: https://github.com/llvm/llvm-project/commit/479f5bfdb02b191f03b3de1a7c3d5a5098b3fcaf DIFF: https://github.com/llvm/llvm-project/commit/479f5bfdb02b191f03b3de1a7c3d5a5098b3fcaf.diff LOG: [LLDB] Improve PDB discovery When loading a PE/COFF target, the associated PDB file often wasn't found. The executable module contains a path for the associated PDB file, but people often debug from a different directory than the one their build system uses. (This is especially common in post-mortem and cross platform debugging.) Suppose the COFF executable being debugged is `~/proj/foo.exe`, but it was built elsewhere and refers to `D:\remote\build\env\foobar.pdb`, LLDB wouldn't find it. With this change, if no file exists at the PDB path, LLDB will look in the executable directory for a PDB file that matches the name of the one it expected (e.g., `~/proj/foobar.pdb`). If found, the PDB is subject to the same matching criteria (GUIDs and age) as would have been used had it been in the original location. This same-directory-as-the-binary rule is commonly used by debuggers on Windows. Differential Review: https://reviews.llvm.org/D84815 Added: lldb/test/Shell/SymbolFile/NativePDB/Inputs/locate-pdb.lldbinit lldb/test/Shell/SymbolFile/NativePDB/locate-pdb.cpp Modified: lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp Removed: ################################################################################ diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp index 9f53e92afa0b..4f7244a340e7 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp @@ -134,8 +134,16 @@ loadMatchingPDBFile(std::string exe_path, llvm::BumpPtrAllocator &allocator) { return nullptr; } - // if the file doesn't exist, is not a pdb, or doesn't have a matching guid, - // fail. + // If the file doesn't exist, perhaps the path specified at build time + // doesn't match the PDB's current location, so check the location of the + // executable. + if (!FileSystem::Instance().Exists(pdb_file)) { + const auto exe_dir = FileSpec(exe_path).CopyByRemovingLastPathComponent(); + const auto pdb_name = FileSpec(pdb_file).GetFilename().GetCString(); + pdb_file = exe_dir.CopyByAppendingPathComponent(pdb_name).GetCString(); + } + + // If the file is not a PDB or if it doesn't have a matching GUID, fail. llvm::file_magic magic; auto ec = llvm::identify_magic(pdb_file, magic); if (ec || magic != llvm::file_magic::pdb) diff --git a/lldb/test/Shell/SymbolFile/NativePDB/Inputs/locate-pdb.lldbinit b/lldb/test/Shell/SymbolFile/NativePDB/Inputs/locate-pdb.lldbinit new file mode 100644 index 000000000000..9d3eab7a3898 --- /dev/null +++ b/lldb/test/Shell/SymbolFile/NativePDB/Inputs/locate-pdb.lldbinit @@ -0,0 +1,2 @@ +target modules dump symfile +quit diff --git a/lldb/test/Shell/SymbolFile/NativePDB/locate-pdb.cpp b/lldb/test/Shell/SymbolFile/NativePDB/locate-pdb.cpp new file mode 100644 index 000000000000..47abea129483 --- /dev/null +++ b/lldb/test/Shell/SymbolFile/NativePDB/locate-pdb.cpp @@ -0,0 +1,34 @@ +// clang-format off +// REQUIRES: lld, x86 + +// Test that lldb can find the PDB file that corresponds to the executable. The linker +// writes a path to the PDB in the executable. If the PDB is not there, lldb should +// check the directory that contains the executable. We'll generate the PDB file in +// a subdirectory and then move it into the directory with the executable. That will +// ensure the PDB path stored in the executable is wrong. + +// Build an EXE and PDB in diff erent directories +// RUN: mkdir -p %t/executable +// RUN: rm -f %t/executable/foo.exe %t/executable/bar.pdb +// RUN: mkdir -p %t/symbols +// RUN: rm -f %t/symbols/bar.pdb +// RUN: %clang_cl --target=x86_64-windows-msvc -Od -Z7 -c /Fo%t/executable/foo.obj -- %s +// RUN: lld-link -debug:full -nodefaultlib -entry:main %t/executable/foo.obj \ +// RUN: -out:%t/executable/foo.exe -pdb:%t/symbols/bar.pdb + +// Find the PDB in its build location +// RUN: env LLDB_USE_NATIVE_PDB_READER=1 %lldb -f %t/executable/foo.exe -s \ +// RUN: %p/Inputs/locate-pdb.lldbinit | FileCheck %s + +// Also find the PDB when it's adjacent to the executable +// RUN: mv -f %t/symbols/bar.pdb %t/executable/bar.pdb +// RUN: env LLDB_USE_NATIVE_PDB_READER=1 %lldb -f %t/executable/foo.exe -s \ +// RUN: %p/Inputs/locate-pdb.lldbinit | FileCheck %s + +int main(int argc, char** argv) { + return 0; +} + +// CHECK: (lldb) target modules dump symfile +// CHECK: Dumping debug symbols for 1 modules. +// CHECK: SymbolFile pdb _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits