-
Notifications
You must be signed in to change notification settings - Fork 15.6k
[symbolizer] Add a --pdb option. #171053
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
[symbolizer] Add a --pdb option. #171053
Conversation
|
@llvm/pr-subscribers-llvm-binary-utilities @llvm/pr-subscribers-debuginfo Author: Yuxuan Shui (yshui) ChangesCloses #142490 Full diff: https://github.com/llvm/llvm-project/pull/171053.diff 6 Files Affected:
diff --git a/llvm/docs/CommandGuide/llvm-symbolizer.rst b/llvm/docs/CommandGuide/llvm-symbolizer.rst
index fb86a694f5d3c..409ad43da127a 100644
--- a/llvm/docs/CommandGuide/llvm-symbolizer.rst
+++ b/llvm/docs/CommandGuide/llvm-symbolizer.rst
@@ -442,6 +442,11 @@ OPTIONS
}
]
+.. option:: --pdb <path>
+
+ Use the specified PDB file at ``<path>``, overriding the PDB info
+ contained in the COFF object.
+
.. option:: --pretty-print, -p
Print human-readable output. If :option:`--inlining` is specified, the
diff --git a/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h b/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h
index fb8f3d8af6b1b..230c57a392f0f 100644
--- a/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h
+++ b/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h
@@ -64,6 +64,7 @@ class LLVMSymbolizer {
std::vector<std::string> DsymHints;
std::string FallbackDebugPath;
std::string DWPName;
+ std::string PDBName;
std::vector<std::string> DebugFileDirectory;
std::vector<std::string> GsymFileDirectory;
size_t MaxCacheSize =
diff --git a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp
index 56527719da51f..9284f1a0565cb 100644
--- a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp
+++ b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp
@@ -662,50 +662,64 @@ LLVMSymbolizer::getOrCreateModuleInfo(StringRef ModuleName) {
ObjectPair Objects = ObjectsOrErr.get();
std::unique_ptr<DIContext> Context;
- // If this is a COFF object containing PDB info and not containing DWARF
- // section, use a PDBContext to symbolize. Otherwise, use DWARF.
- // Create a DIContext to symbolize as follows:
- // - If there is a GSYM file, create a GsymContext.
- // - Otherwise, if this is a COFF object containing PDB info, create a
- // PDBContext.
- // - Otherwise, create a DWARFContext.
- const auto GsymFile = lookUpGsymFile(BinaryName.str());
- if (!GsymFile.empty()) {
- auto ReaderOrErr = gsym::GsymReader::openFile(GsymFile);
-
- if (ReaderOrErr) {
- std::unique_ptr<gsym::GsymReader> Reader =
- std::make_unique<gsym::GsymReader>(std::move(*ReaderOrErr));
-
- Context = std::make_unique<gsym::GsymContext>(std::move(Reader));
+ pdb::PDB_ReaderType ReaderType =
+ Opts.UseDIA ? pdb::PDB_ReaderType::DIA : pdb::PDB_ReaderType::Native;
+ const auto *CoffObject = dyn_cast<COFFObjectFile>(Objects.first);
+
+ // First, if the user specified a pdb file on the command line, use that.
+ if (CoffObject && !Opts.PDBName.empty()) {
+ using namespace pdb;
+ std::unique_ptr<IPDBSession> Session;
+ if (auto Err = loadDataForPDB(ReaderType, Opts.PDBName, Session)) {
+ Modules.emplace(ModuleName, std::unique_ptr<SymbolizableModule>());
+ return createFileError(Opts.PDBName, std::move(Err));
}
+ Context.reset(new PDBContext(*CoffObject, std::move(Session)));
}
+
if (!Context) {
- if (auto CoffObject = dyn_cast<COFFObjectFile>(Objects.first)) {
- const codeview::DebugInfo *DebugInfo;
- StringRef PDBFileName;
- auto EC = CoffObject->getDebugPDBInfo(DebugInfo, PDBFileName);
- // Use DWARF if there're DWARF sections.
- bool HasDwarf = llvm::any_of(
- Objects.first->sections(), [](SectionRef Section) -> bool {
- if (Expected<StringRef> SectionName = Section.getName())
- return SectionName.get() == ".debug_info";
- return false;
- });
- if (!EC && !HasDwarf && DebugInfo != nullptr && !PDBFileName.empty()) {
- using namespace pdb;
- std::unique_ptr<IPDBSession> Session;
-
- PDB_ReaderType ReaderType =
- Opts.UseDIA ? PDB_ReaderType::DIA : PDB_ReaderType::Native;
- if (auto Err = loadDataForEXE(ReaderType, Objects.first->getFileName(),
- Session)) {
- Modules.emplace(ModuleName, std::unique_ptr<SymbolizableModule>());
- // Return along the PDB filename to provide more context
- return createFileError(PDBFileName, std::move(Err));
- }
- Context.reset(new PDBContext(*CoffObject, std::move(Session)));
+ // If this is a COFF object containing PDB info and not containing DWARF
+ // section, use a PDBContext to symbolize. Otherwise, use DWARF.
+ // Create a DIContext to symbolize as follows:
+ // - If there is a GSYM file, create a GsymContext.
+ // - Otherwise, if this is a COFF object containing PDB info, create a
+ // PDBContext.
+ // - Otherwise, create a DWARFContext.
+ const auto GsymFile = lookUpGsymFile(BinaryName.str());
+ if (!GsymFile.empty()) {
+ auto ReaderOrErr = gsym::GsymReader::openFile(GsymFile);
+
+ if (ReaderOrErr) {
+ std::unique_ptr<gsym::GsymReader> Reader =
+ std::make_unique<gsym::GsymReader>(std::move(*ReaderOrErr));
+
+ Context = std::make_unique<gsym::GsymContext>(std::move(Reader));
+ }
+ }
+ }
+
+ if (!Context && CoffObject) {
+ const codeview::DebugInfo *DebugInfo;
+ StringRef PDBFileName;
+ auto EC = CoffObject->getDebugPDBInfo(DebugInfo, PDBFileName);
+ // Use DWARF if there're DWARF sections.
+ bool HasDwarf = llvm::any_of(
+ Objects.first->sections(), [](SectionRef Section) -> bool {
+ if (Expected<StringRef> SectionName = Section.getName())
+ return SectionName.get() == ".debug_info";
+ return false;
+ });
+ if (!EC && !HasDwarf && DebugInfo != nullptr && !PDBFileName.empty()) {
+ using namespace pdb;
+ std::unique_ptr<IPDBSession> Session;
+
+ if (auto Err = loadDataForEXE(ReaderType, Objects.first->getFileName(),
+ Session)) {
+ Modules.emplace(ModuleName, std::unique_ptr<SymbolizableModule>());
+ // Return along the PDB filename to provide more context
+ return createFileError(PDBFileName, std::move(Err));
}
+ Context.reset(new PDBContext(*CoffObject, std::move(Session)));
}
}
if (!Context)
diff --git a/llvm/test/tools/llvm-symbolizer/pdb/pdb.test b/llvm/test/tools/llvm-symbolizer/pdb/pdb.test
index 46a1ae9814e6d..a9d79cffb7d12 100644
--- a/llvm/test/tools/llvm-symbolizer/pdb/pdb.test
+++ b/llvm/test/tools/llvm-symbolizer/pdb/pdb.test
@@ -1,3 +1,6 @@
+RUN: rm -rf %t
+RUN: mkdir -p %t
+
RUN: echo 0x401380 > %t.input
RUN: echo 0x401390 >> %t.input
RUN: echo 0x4013A0 >> %t.input
@@ -11,6 +14,10 @@ RUN: | FileCheck %s
RUN: llvm-symbolizer --obj="%p/Inputs/test.exe" --no-demangle < %t.input \
RUN: | FileCheck %s --check-prefix=CHECK-NO-DEMANGLE
+RUN: cp %p/Inputs/test.exe %t/test.exe
+RUN: llvm-symbolizer --obj="%t/test.exe" --pdb="%p/Inputs/test.pdb" < %t.input \
+RUN: | FileCheck %s
+
; Check that -dia works
RUN: llvm-symbolizer --dia --obj="%p/Inputs/test.exe" < %t.input \
RUN: | FileCheck %s
diff --git a/llvm/tools/llvm-symbolizer/Opts.td b/llvm/tools/llvm-symbolizer/Opts.td
index 10f1e6dbbddf7..ddbd4471f4452 100644
--- a/llvm/tools/llvm-symbolizer/Opts.td
+++ b/llvm/tools/llvm-symbolizer/Opts.td
@@ -41,6 +41,7 @@ def functions_EQ : Joined<["--"], "functions=">, HelpText<"Print function name f
defm gsym_file_directory : Eq<"gsym-file-directory", "Path to directory where to look for GSYM files">, MetaVarName<"<dir>">, Group<grp_gsym>;
def help : F<"help", "Display this help">;
defm dwp : Eq<"dwp", "Path to DWP file to be use for any split CUs">, MetaVarName<"<file>">;
+defm pdb : Eq<"pdb", "Path to PDB file">, MetaVarName<"<file>">;
defm dsym_hint
: Eq<"dsym-hint",
"Path to .dSYM bundles to search for debug info for the object files">,
diff --git a/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp b/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp
index 4784dafeb2948..1b9fcf35cd4ef 100644
--- a/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp
+++ b/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp
@@ -500,6 +500,7 @@ int llvm_symbolizer_main(int argc, char **argv, const llvm::ToolContext &) {
Opts.DefaultArch = Args.getLastArgValue(OPT_default_arch_EQ).str();
Opts.Demangle = Args.hasFlag(OPT_demangle, OPT_no_demangle, !IsAddr2Line);
Opts.DWPName = Args.getLastArgValue(OPT_dwp_EQ).str();
+ Opts.PDBName = Args.getLastArgValue(OPT_pdb_EQ).str();
Opts.FallbackDebugPath =
Args.getLastArgValue(OPT_fallback_debug_path_EQ).str();
Opts.GsymFileDirectory = Args.getAllArgValues(OPT_gsym_file_directory_EQ);
|
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
|
@mstorsjo, can you recommend anybody to review this item? COFF PDB is outside my area of knowledge, so I don't feel comfortable reviewing it myself. |
Closes #142490