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,24 @@ +// clang-format off +// REQUIRES: lld + +// Test that we can find .pdb file in folder containing .exe file. +// 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 + + +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: 11 +// CHECK: 12 int main(int argc, char **argv) { +// CHECK: 13 // Here are some comments. +// CHECK: 14 return 0; +// CHECK: 15 } +// CHECK: 16 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,43 @@ return File; } + +static std::string findPdbFile(const llvm::StringRef exe_path, const llvm::StringRef pdb_file, llvm::file_magic &magic) { + auto ec = llvm::identify_magic(pdb_file, magic); + if (!ec) + return pdb_file; + + auto 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) + return path.str(); + + llvm::StringRef nt_symbol_path = ::getenv("_NT_SYMBOL_PATH"); + llvm::SmallVector parts; + nt_symbol_path.split(parts, ';', -1, false); + + for (auto 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) { + 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 +167,14 @@ if (ec) return nullptr; + llvm::file_magic magic; + auto pdb_full_path = findPdbFile(exe_path, pdb_file, magic); + // 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() || magic != llvm::file_magic::pdb) return nullptr; - std::unique_ptr pdb = loadPDBFile(pdb_file, allocator); + std::unique_ptr pdb = loadPDBFile(pdb_full_path, allocator); if (!pdb) return nullptr;