-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[Symbolize] Always use filename:line from debug info when debug info for the given address is available. #128619
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
Conversation
… indicate if debug info is present or not for a given address.
…for the given address is available.
@llvm/pr-subscribers-platform-windows @llvm/pr-subscribers-debuginfo Author: Zequan Wu (ZequanWu) ChangesIt has two commits: d76efd8 adds the APIs to Full diff: https://github.com/llvm/llvm-project/pull/128619.diff 9 Files Affected:
diff --git a/llvm/include/llvm/DebugInfo/BTF/BTFContext.h b/llvm/include/llvm/DebugInfo/BTF/BTFContext.h
index c16bee6133220..b9c7cd5ede7bc 100644
--- a/llvm/include/llvm/DebugInfo/BTF/BTFContext.h
+++ b/llvm/include/llvm/DebugInfo/BTF/BTFContext.h
@@ -48,6 +48,12 @@ class BTFContext final : public DIContext {
std::vector<DILocal>
getLocalsForAddress(object::SectionedAddress Address) override;
+ std::optional<DILineInfo> getOptionalLineInfoForAddress(
+ object::SectionedAddress Address,
+ DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
+ std::optional<DILineInfo>
+ getOptionalLineInfoForDataAddress(object::SectionedAddress Address) override;
+
static std::unique_ptr<BTFContext> create(
const object::ObjectFile &Obj,
std::function<void(Error)> ErrorHandler = WithColor::defaultErrorHandler);
diff --git a/llvm/include/llvm/DebugInfo/DIContext.h b/llvm/include/llvm/DebugInfo/DIContext.h
index 71685ba09d8db..d7990092ec8fa 100644
--- a/llvm/include/llvm/DebugInfo/DIContext.h
+++ b/llvm/include/llvm/DebugInfo/DIContext.h
@@ -267,6 +267,12 @@ class DIContext {
virtual std::vector<DILocal>
getLocalsForAddress(object::SectionedAddress Address) = 0;
+ virtual std::optional<DILineInfo> getOptionalLineInfoForAddress(
+ object::SectionedAddress Address,
+ DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0;
+ virtual std::optional<DILineInfo>
+ getOptionalLineInfoForDataAddress(object::SectionedAddress Address) = 0;
+
private:
const DIContextKind Kind;
};
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h
index 0d6e2b076cc34..6ea909480926c 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h
@@ -401,6 +401,12 @@ class DWARFContext : public DIContext {
std::vector<DILocal>
getLocalsForAddress(object::SectionedAddress Address) override;
+ std::optional<DILineInfo> getOptionalLineInfoForAddress(
+ object::SectionedAddress Address,
+ DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
+ std::optional<DILineInfo>
+ getOptionalLineInfoForDataAddress(object::SectionedAddress Address) override;
+
bool isLittleEndian() const { return DObj->isLittleEndian(); }
static unsigned getMaxSupportedVersion() { return 5; }
static bool isSupportedVersion(unsigned version) {
diff --git a/llvm/include/llvm/DebugInfo/PDB/PDBContext.h b/llvm/include/llvm/DebugInfo/PDB/PDBContext.h
index 3163c0a1dae03..1f436a705b072 100644
--- a/llvm/include/llvm/DebugInfo/PDB/PDBContext.h
+++ b/llvm/include/llvm/DebugInfo/PDB/PDBContext.h
@@ -57,6 +57,12 @@ namespace pdb {
std::vector<DILocal>
getLocalsForAddress(object::SectionedAddress Address) override;
+ std::optional<DILineInfo> getOptionalLineInfoForAddress(
+ object::SectionedAddress Address,
+ DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
+ std::optional<DILineInfo> getOptionalLineInfoForDataAddress(
+ object::SectionedAddress Address) override;
+
private:
std::string getFunctionName(uint64_t Address, DINameKind NameKind) const;
std::unique_ptr<IPDBSession> Session;
diff --git a/llvm/lib/DebugInfo/BTF/BTFContext.cpp b/llvm/lib/DebugInfo/BTF/BTFContext.cpp
index 2e651cb378dbf..0b172bf8c3fe3 100644
--- a/llvm/lib/DebugInfo/BTF/BTFContext.cpp
+++ b/llvm/lib/DebugInfo/BTF/BTFContext.cpp
@@ -20,6 +20,17 @@ using namespace llvm;
using object::ObjectFile;
using object::SectionedAddress;
+std::optional<DILineInfo>
+BTFContext::getOptionalLineInfoForAddress(object::SectionedAddress Address,
+ DILineInfoSpecifier Specifier) {
+ return getLineInfoForAddress(Address, Specifier);
+}
+
+std::optional<DILineInfo> BTFContext::getOptionalLineInfoForDataAddress(
+ object::SectionedAddress Address) {
+ return getLineInfoForDataAddress(Address);
+}
+
DILineInfo BTFContext::getLineInfoForAddress(SectionedAddress Address,
DILineInfoSpecifier Specifier) {
const BTF::BPFLineInfo *LineInfo = BTF.findLineInfo(Address);
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
index 99e1642ff23ad..a2955cc2a7f55 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
@@ -1732,11 +1732,21 @@ DWARFContext::getLocalsForAddress(object::SectionedAddress Address) {
DILineInfo DWARFContext::getLineInfoForAddress(object::SectionedAddress Address,
DILineInfoSpecifier Spec) {
- DILineInfo Result;
+ std::optional<DILineInfo> Result =
+ getOptionalLineInfoForAddress(Address, Spec);
+ if (Result)
+ return *Result;
+ return DILineInfo();
+}
+
+std::optional<DILineInfo>
+DWARFContext::getOptionalLineInfoForAddress(object::SectionedAddress Address,
+ DILineInfoSpecifier Spec) {
DWARFCompileUnit *CU = getCompileUnitForCodeAddress(Address.Address);
if (!CU)
- return Result;
+ return std::nullopt;
+ DILineInfo Result;
getFunctionNameAndStartLineForAddress(
CU, Address.Address, Spec.FNKind, Spec.FLIKind, Result.FunctionName,
Result.StartFileName, Result.StartLine, Result.StartAddress);
@@ -1753,17 +1763,25 @@ DILineInfo DWARFContext::getLineInfoForAddress(object::SectionedAddress Address,
DILineInfo
DWARFContext::getLineInfoForDataAddress(object::SectionedAddress Address) {
- DILineInfo Result;
+ std::optional<DILineInfo> Result = getOptionalLineInfoForDataAddress(Address);
+ if (Result)
+ return *Result;
+ return DILineInfo();
+}
+
+std::optional<DILineInfo> DWARFContext::getOptionalLineInfoForDataAddress(
+ object::SectionedAddress Address) {
DWARFCompileUnit *CU = getCompileUnitForDataAddress(Address.Address);
if (!CU)
- return Result;
+ return std::nullopt;
if (DWARFDie Die = CU->getVariableForAddress(Address.Address)) {
+ DILineInfo Result;
Result.FileName = Die.getDeclFile(FileLineInfoKind::AbsoluteFilePath);
Result.Line = Die.getDeclLine();
+ return Result;
}
-
- return Result;
+ return std::nullopt;
}
DILineInfoTable DWARFContext::getLineInfoForAddressRange(
diff --git a/llvm/lib/DebugInfo/PDB/PDBContext.cpp b/llvm/lib/DebugInfo/PDB/PDBContext.cpp
index e600fb7385f13..462cb70c95579 100644
--- a/llvm/lib/DebugInfo/PDB/PDBContext.cpp
+++ b/llvm/lib/DebugInfo/PDB/PDBContext.cpp
@@ -32,6 +32,17 @@ PDBContext::PDBContext(const COFFObjectFile &Object,
void PDBContext::dump(raw_ostream &OS, DIDumpOptions DumpOpts){}
+std::optional<DILineInfo>
+PDBContext::getOptionalLineInfoForAddress(object::SectionedAddress Address,
+ DILineInfoSpecifier Specifier) {
+ return getLineInfoForAddress(Address, Specifier);
+}
+
+std::optional<DILineInfo> PDBContext::getOptionalLineInfoForDataAddress(
+ object::SectionedAddress Address) {
+ return getLineInfoForDataAddress(Address);
+}
+
DILineInfo PDBContext::getLineInfoForAddress(object::SectionedAddress Address,
DILineInfoSpecifier Specifier) {
DILineInfo Result;
diff --git a/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp b/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp
index d5e1dc759df5c..69cf992a26842 100644
--- a/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp
+++ b/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp
@@ -276,9 +276,12 @@ SymbolizableObjectFile::symbolizeCode(object::SectionedAddress ModuleOffset,
if (ModuleOffset.SectionIndex == object::SectionedAddress::UndefSection)
ModuleOffset.SectionIndex =
getModuleSectionIndexForAddress(ModuleOffset.Address);
- DILineInfo LineInfo =
- DebugInfoContext->getLineInfoForAddress(ModuleOffset, LineInfoSpecifier);
-
+ DILineInfo LineInfo;
+ std::optional<DILineInfo> DBGLineInfo =
+ DebugInfoContext->getOptionalLineInfoForAddress(ModuleOffset,
+ LineInfoSpecifier);
+ if (DBGLineInfo)
+ LineInfo = *DBGLineInfo;
// Override function name from symbol table if necessary.
if (shouldOverrideWithSymbolTable(LineInfoSpecifier.FNKind, UseSymbolTable)) {
std::string FunctionName, FileName;
@@ -287,7 +290,7 @@ SymbolizableObjectFile::symbolizeCode(object::SectionedAddress ModuleOffset,
FileName)) {
LineInfo.FunctionName = FunctionName;
LineInfo.StartAddress = Start;
- if (LineInfo.FileName == DILineInfo::BadString && !FileName.empty())
+ if (!DBGLineInfo && !FileName.empty())
LineInfo.FileName = FileName;
}
}
@@ -304,8 +307,11 @@ DIInliningInfo SymbolizableObjectFile::symbolizeInlinedCode(
ModuleOffset, LineInfoSpecifier);
// Make sure there is at least one frame in context.
- if (InlinedContext.getNumberOfFrames() == 0)
+ bool EmptyFrameAdded = false;
+ if (InlinedContext.getNumberOfFrames() == 0) {
+ EmptyFrameAdded = true;
InlinedContext.addFrame(DILineInfo());
+ }
// Override the function name in lower frame with name from symbol table.
if (shouldOverrideWithSymbolTable(LineInfoSpecifier.FNKind, UseSymbolTable)) {
@@ -317,7 +323,7 @@ DIInliningInfo SymbolizableObjectFile::symbolizeInlinedCode(
InlinedContext.getNumberOfFrames() - 1);
LI->FunctionName = FunctionName;
LI->StartAddress = Start;
- if (LI->FileName == DILineInfo::BadString && !FileName.empty())
+ if (EmptyFrameAdded && !FileName.empty())
LI->FileName = FileName;
}
}
@@ -334,10 +340,11 @@ DIGlobal SymbolizableObjectFile::symbolizeData(
Res.DeclFile = FileName;
// Try and get a better filename:lineno pair from the debuginfo, if present.
- DILineInfo DL = DebugInfoContext->getLineInfoForDataAddress(ModuleOffset);
- if (DL.Line != 0) {
- Res.DeclFile = DL.FileName;
- Res.DeclLine = DL.Line;
+ std::optional<DILineInfo> DL =
+ DebugInfoContext->getOptionalLineInfoForDataAddress(ModuleOffset);
+ if (DL) {
+ Res.DeclFile = DL->FileName;
+ Res.DeclLine = DL->Line;
}
return Res;
}
diff --git a/llvm/test/tools/llvm-symbolizer/debug-info-line-info.yaml b/llvm/test/tools/llvm-symbolizer/debug-info-line-info.yaml
new file mode 100644
index 0000000000000..94460e586a540
--- /dev/null
+++ b/llvm/test/tools/llvm-symbolizer/debug-info-line-info.yaml
@@ -0,0 +1,175 @@
+# Test llvm-symbolizer always uses line info from debug info if present.
+# RUN: yaml2obj %s -o %t
+# RUN: llvm-symbolizer --obj=%t 0x1 | FileCheck %s
+
+# CHECK: foo(bool)
+# CHECK-NEXT: ??:0:0
+
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_REL
+ Machine: EM_X86_64
+ SectionHeaderStringTable: .strtab
+Sections:
+ - Name: .text
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ AddressAlign: 0x10
+ Content: 50E80000000031C059C3
+ - Name: .debug_abbrev
+ Type: SHT_PROGBITS
+ AddressAlign: 0x1
+ Content: 01110025251305032572171017111B12067317000000
+ - Name: .debug_info
+ Type: SHT_PROGBITS
+ AddressAlign: 0x1
+ Content: 1E000000050001080000000001002100010000000000000000000A00000000000000
+ - Name: .debug_str_offsets
+ Type: SHT_PROGBITS
+ AddressAlign: 0x1
+ Content: 0C000000050000000000000000000000
+ - Name: .debug_line
+ Type: SHT_PROGBITS
+ AddressAlign: 0x1
+ Content: 5C0000000500080037000000010101FB0E0D00010101010000000100000101011F010000000003011F020F051E0100000000009C5BB3AA3D0567AB9CB3F5A35C9F9B230400000902000000000000000013061E0505060A5F060B2E0202000101
+ - Name: .debug_line_str
+ Type: SHT_PROGBITS
+ Flags: [ SHF_MERGE, SHF_STRINGS ]
+ AddressAlign: 0x1
+ EntSize: 0x1
+ Content: 003C696E76616C69643E00
+ - Name: .rela.text
+ Type: SHT_RELA
+ Flags: [ SHF_INFO_LINK ]
+ Link: .symtab
+ AddressAlign: 0x8
+ Info: .text
+ Relocations:
+ - Offset: 0x2
+ Symbol: _Z3barv
+ Type: R_X86_64_PLT32
+ Addend: -4
+ - Name: .rela.debug_info
+ Type: SHT_RELA
+ Flags: [ SHF_INFO_LINK ]
+ Link: .symtab
+ AddressAlign: 0x8
+ Info: .debug_info
+ Relocations:
+ - Offset: 0x8
+ Symbol: .debug_abbrev
+ Type: R_X86_64_32
+ - Offset: 0x11
+ Symbol: .debug_str_offsets
+ Type: R_X86_64_32
+ Addend: 8
+ - Offset: 0x15
+ Symbol: .debug_line
+ Type: R_X86_64_32
+ - Offset: 0x1E
+ Symbol: .debug_addr
+ Type: R_X86_64_32
+ Addend: 8
+ - Name: .rela.debug_str_offsets
+ Type: SHT_RELA
+ Flags: [ SHF_INFO_LINK ]
+ Link: .symtab
+ AddressAlign: 0x8
+ Info: .debug_str_offsets
+ Relocations:
+ - Offset: 0x8
+ Symbol: .debug_str
+ Type: R_X86_64_32
+ - Offset: 0xC
+ Symbol: .debug_str
+ Type: R_X86_64_32
+ Addend: 24
+ - Name: .rela.debug_addr
+ Type: SHT_RELA
+ Flags: [ SHF_INFO_LINK ]
+ Link: .symtab
+ AddressAlign: 0x8
+ Info: .debug_addr
+ Relocations:
+ - Offset: 0x8
+ Symbol: .text
+ Type: R_X86_64_64
+ - Name: .rela.debug_line
+ Type: SHT_RELA
+ Flags: [ SHF_INFO_LINK ]
+ Link: .symtab
+ AddressAlign: 0x8
+ Info: .debug_line
+ Relocations:
+ - Offset: 0x22
+ Symbol: .debug_line_str
+ Type: R_X86_64_32
+ - Offset: 0x2E
+ Symbol: .debug_line_str
+ Type: R_X86_64_32
+ Addend: 1
+ - Offset: 0x48
+ Symbol: .text
+ Type: R_X86_64_64
+ - Type: SectionHeaderTable
+ Sections:
+ - Name: .strtab
+ - Name: .text
+ - Name: .rela.text
+ - Name: .debug_abbrev
+ - Name: .debug_info
+ - Name: .rela.debug_info
+ - Name: .debug_str_offsets
+ - Name: .rela.debug_str_offsets
+ - Name: .debug_str
+ - Name: .debug_addr
+ - Name: .rela.debug_addr
+ - Name: .debug_line
+ - Name: .rela.debug_line
+ - Name: .debug_line_str
+ - Name: .symtab
+Symbols:
+ - Name: main.cpp
+ Type: STT_FILE
+ Index: SHN_ABS
+ - Name: .text
+ Type: STT_SECTION
+ Section: .text
+ - Name: .debug_abbrev
+ Type: STT_SECTION
+ Section: .debug_abbrev
+ - Name: .debug_str_offsets
+ Type: STT_SECTION
+ Section: .debug_str_offsets
+ - Name: .debug_str
+ Type: STT_SECTION
+ Section: .debug_str
+ - Name: .debug_addr
+ Type: STT_SECTION
+ Section: .debug_addr
+ - Name: .debug_line
+ Type: STT_SECTION
+ Section: .debug_line
+ - Name: .debug_line_str
+ Type: STT_SECTION
+ Section: .debug_line_str
+ - Name: _Z3foob
+ Type: STT_FUNC
+ Section: .text
+ Binding: STB_LOCAL
+ Size: 0xA
+ - Name: _Z3barv
+ Binding: STB_LOCAL
+DWARF:
+ debug_str:
+ - clang version 21.0.0git
+ - '<invalid>'
+ debug_addr:
+ - Length: 0xC
+ Version: 0x5
+ AddressSize: 0x8
+ Entries:
+ - {}
+...
|
Feels a bit awkward to add new virtual functions for this - when, at least I think in theory, the new virtual functions are strictly more expressivse than the old ones (so, one option would be to rename the virtual functions to add the new behavior, then add non-virtual wrapping functions that provide the old behavior under the original name). But, also - maybe this isn't the level at which to make the change? Perhaps inside the DILine Info, the file/line number should be wrapped in an optional, so it's clear that neither of those things is present/valid? |
I share this concern, and I think there is already a lot of prior art for expressing ideas like "source" and "confidence level" inside of the DILineInfo struct. What is the meaning of the |
Switching to bundle the file/line/column/whatever else (source I guess, because no need to carry source if you don't know which file it is in anyway) optional would require more explicit cleanup, but I'd prefer that (the data structure would be more self descriptive/constrained) than adding an extra boolean. The |
Because there are so many places use those original APIs, making them to return optional requires large scale change. For the same reason, I didn't go the way to make file/line optional. |
We aren't usually trying to optimize for the size of a change, within reason. (doing so tends to lead to a codebase that becomes harder to maintain over time because it lacks a unifying design) |
✅ With the latest revision this PR passed the C/C++ code formatter. |
I looked at our internal failed test again. I was wrong about why our internal test failed. I thought it was because symbolizer chooses the filename from symbol table when the filename from debug info is |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Disregard the above comment. It's actually possible to have <invalid>:0
debug info after #124846. I missed something when reproing internal test failure.
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/160/builds/15360 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/65/builds/14403 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/180/builds/15357 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/154/builds/13950 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/190/builds/17098 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/54/builds/7672 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/155/builds/7838 Here is the relevant piece of the build log for the reference
|
@ZequanWu the test |
I believe you need a REQUIRES line if you are going to reference a specific target https://lab.llvm.org/buildbot/#/builders/190/builds/17106
|
…24846)" This land commits 23aca2f and 1b15a89. llvm#128619 makes symbolizer to always use debug info when available so we can reland this chagnge.
…ble (#124846)" (#133798) This land commits 23aca2f and 1b15a89. llvm/llvm-project#128619 makes symbolizer to always use debug info when available so we can reland this chagnge.
…#124846)" (#133798)" This reverts commit 3483740 because #128619 doesn't handle the case when we have an empty frame from `getInliningInfoForAddress` because line num is 0 which makes it non-differentiable from missing debug info. So, we end up using the base filename from symtab again. Reverting for now until that issus is solved.
…llvm#124846)" (llvm#133798)" This reverts commit 3483740 because llvm#128619 doesn't handle the case when we have an empty frame from `getInliningInfoForAddress` because line num is 0 which makes it non-differentiable from missing debug info. So, we end up using the base filename from symtab again. Reverting for now until that issus is solved.
…llvm#124846)" (llvm#133798)" This reverts commit 3483740 because llvm#128619 doesn't handle the case when we have an empty frame from `getInliningInfoForAddress` because line num is 0 which makes it non-differentiable from missing debug info. So, we end up using the base filename from symtab again. Reverting for now until that issus is solved.
To reland #124846, we need to make symbolizer consistent with the case when line number is 0. Always using filename and line from debug info even if the line number is 0 sounds like the reasonable path to go.