Index: lldb/lit/SymbolFile/NativePDB/Inputs/pdb-file-lookup.lldbinit =================================================================== --- /dev/null +++ lldb/lit/SymbolFile/NativePDB/Inputs/pdb-file-lookup.lldbinit @@ -0,0 +1,2 @@ +source list -n main +quit Index: lldb/lit/SymbolFile/NativePDB/pdb-file-lookup.cpp =================================================================== --- /dev/null +++ lldb/lit/SymbolFile/NativePDB/pdb-file-lookup.cpp @@ -0,0 +1,31 @@ +// clang-format off +// REQUIRES: lld + +// Test that we can find .pdb file in _NT_SYMBOL_PATH folder. +// RUN: %build --compiler=clang-cl --nodefaultlib -o %t.exe -- %s +// RUN: mkdir -p %t +// RUN: mv %t.pdb %t/pdb-file-lookup.cpp.tmp.pdb +// RUN: env _NT_SYMBOL_PATH=%t LLDB_USE_NATIVE_PDB_READER=1 %lldb -f %t.exe -s \ +// RUN: %p/Inputs/pdb-file-lookup.lldbinit | FileCheck %s +// +// Test that we can find .pdb file in folder containing .exe file. +// RUN: mv %t.exe %t/pdb-file-lookup.cpp.tmp.exe +// RUN: env LLDB_USE_NATIVE_PDB_READER=1 %lldb -f \ +// RUN: %t/pdb-file-lookup.cpp.tmp.exe -s \ +// RUN: %p/Inputs/pdb-file-lookup.lldbinit | FileCheck %s + + + +int main(int argc, char **argv) { + // Here are some comments. + return 0; +} + +// CHECK: (lldb) source list -n main +// CHECK: File: {{.*}}pdb-file-lookup.cpp +// CHECK: 18 +// CHECK: 19 int main(int argc, char **argv) { +// CHECK: 20 // Here are some comments. +// CHECK: 21 return 0; +// CHECK: 22 } +// CHECK: 23 Index: lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp +++ lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp @@ -106,6 +106,45 @@ return File; } + +static std::string findPdbFile(llvm::StringRef exe_path, + llvm::StringRef pdb_file) { + llvm::file_magic magic; + std::error_code ec = llvm::identify_magic(pdb_file, magic); + if (!ec && magic == llvm::file_magic::pdb) + return pdb_file; + + llvm::StringRef pdb_file_name = llvm::sys::path::filename(pdb_file); + + llvm::SmallString<128> path = exe_path; + llvm::sys::path::remove_filename(path); + llvm::sys::path::append(path, pdb_file_name); + + ec = llvm::identify_magic(path, magic); + if (!ec && magic == llvm::file_magic::pdb) + return path.str(); + + llvm::StringRef nt_symbol_path = ::getenv("_NT_SYMBOL_PATH"); + llvm::SmallVector parts; + nt_symbol_path.split(parts, ';', -1, false); + + for (llvm::StringRef part_ref : parts) { + if (part_ref.startswith_lower("srv*")) { + //Symbol servers is not supported yet + continue; + } + + path = part_ref; + llvm::sys::path::append(path, pdb_file_name); + + ec = llvm::identify_magic(path, magic); + if (!ec && magic == llvm::file_magic::pdb) { + return path.str(); + } + } + + return {}; +} static std::unique_ptr loadMatchingPDBFile(std::string exe_path, llvm::BumpPtrAllocator &allocator) { // Try to find a matching PDB for an EXE. @@ -130,13 +169,13 @@ if (ec) return nullptr; + auto pdb_full_path = findPdbFile(exe_path, pdb_file); + // if the file doesn't exist, is not a pdb, or doesn't have a matching guid, // fail. - llvm::file_magic magic; - ec = llvm::identify_magic(pdb_file, magic); - if (ec || magic != llvm::file_magic::pdb) + if (pdb_full_path.empty()) return nullptr; - std::unique_ptr pdb = loadPDBFile(pdb_file, allocator); + std::unique_ptr pdb = loadPDBFile(pdb_full_path, allocator); if (!pdb) return nullptr;