[llvm] [DWARFVerifier] Fix infinite loop in verifyDebugInfoCallSite (PR #186413)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Mar 13 08:24:02 PDT 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-debuginfo
Author: None (youngd007)
<details>
<summary>Changes</summary>
When attempting to find the callsite for a DwarfDie to see if it was valid or not, there was a while loop that incorrectly attempted to walk up the Die parent hierarch. It set `curr` to parent, but then `curr` was set to same original parent instead of curr.getParent(). This caused infinite recursion on validation of some kernel binaries by llvm-dwarfdump where DW_TAG_call_site was nested inside a DW_TAG_lexical_block (or any non-subprogram, non-inlined_subroutine tag).
Fix by changing Die.getParent() to Curr.getParent() so the loop correctly walks up the DIE tree.
Add a new test that validates this scenario. Without this change, that test hangs rather than succeeding.
---
Full diff: https://github.com/llvm/llvm-project/pull/186413.diff
2 Files Affected:
- (modified) llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp (+1-1)
- (added) llvm/test/tools/llvm-dwarfdump/X86/callsite-in-lexical-block.yaml (+105)
``````````diff
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp b/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
index 05191f68e0ddd..acfe1e02921d2 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
@@ -329,7 +329,7 @@ unsigned DWARFVerifier::verifyDebugInfoCallSite(const DWARFDie &Die) {
return 0;
DWARFDie Curr = Die.getParent();
- for (; Curr.isValid() && !Curr.isSubprogramDIE(); Curr = Die.getParent()) {
+ for (; Curr.isValid() && !Curr.isSubprogramDIE(); Curr = Curr.getParent()) {
if (Curr.getTag() == DW_TAG_inlined_subroutine) {
ErrorCategory.Report(
"Call site nested entry within inlined subroutine", [&]() {
diff --git a/llvm/test/tools/llvm-dwarfdump/X86/callsite-in-lexical-block.yaml b/llvm/test/tools/llvm-dwarfdump/X86/callsite-in-lexical-block.yaml
new file mode 100644
index 0000000000000..219fa8a82f0b4
--- /dev/null
+++ b/llvm/test/tools/llvm-dwarfdump/X86/callsite-in-lexical-block.yaml
@@ -0,0 +1,105 @@
+## Test that llvm-dwarfdump --verify correctly handles DW_TAG_call_site
+## nested inside a DW_TAG_lexical_block. Previously, the parent-walking
+## loop in verifyDebugInfoCallSite() used Die.getParent() instead of
+## Curr.getParent(), causing an infinite loop when the call_site's
+## immediate parent was not a subprogram (e.g., a lexical_block).
+
+# RUN: yaml2obj %s -o %t.o
+# RUN: llvm-dwarfdump --verify %t.o 2>&1 | FileCheck %s
+
+# CHECK: No errors.
+
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_EXEC
+ Machine: EM_X86_64
+DWARF:
+ debug_str:
+ - "callee"
+ - "caller"
+
+ debug_abbrev:
+ - Table:
+ - Code: 0x00000001
+ Tag: DW_TAG_compile_unit
+ Children: DW_CHILDREN_yes
+ Attributes:
+ - Attribute: DW_AT_low_pc
+ Form: DW_FORM_addr
+ - Code: 0x00000002
+ Tag: DW_TAG_subprogram
+ Children: DW_CHILDREN_no
+ Attributes:
+ - Attribute: DW_AT_name
+ Form: DW_FORM_strp
+ - Attribute: DW_AT_low_pc
+ Form: DW_FORM_addr
+ - Attribute: DW_AT_high_pc
+ Form: DW_FORM_data4
+ - Code: 0x00000003
+ Tag: DW_TAG_subprogram
+ Children: DW_CHILDREN_yes
+ Attributes:
+ - Attribute: DW_AT_name
+ Form: DW_FORM_strp
+ - Attribute: DW_AT_low_pc
+ Form: DW_FORM_addr
+ - Attribute: DW_AT_high_pc
+ Form: DW_FORM_data4
+ - Attribute: DW_AT_call_all_calls
+ Form: DW_FORM_flag_present
+ - Code: 0x00000004
+ Tag: DW_TAG_lexical_block
+ Children: DW_CHILDREN_yes
+ Attributes:
+ - Attribute: DW_AT_low_pc
+ Form: DW_FORM_addr
+ - Attribute: DW_AT_high_pc
+ Form: DW_FORM_data4
+ - Code: 0x00000005
+ Tag: DW_TAG_call_site
+ Children: DW_CHILDREN_no
+ Attributes:
+ - Attribute: DW_AT_call_origin
+ Form: DW_FORM_ref4
+
+ debug_info:
+ - Version: 5
+ UnitType: DW_UT_compile
+ AbbrOffset: 0x00000000
+ AddrSize: 8
+ Entries:
+ # DW_TAG_compile_unit
+ - AbbrCode: 0x00000001
+ Values:
+ - Value: 0x0000000000000000 # DW_AT_low_pc
+ # DW_TAG_subprogram (callee) - offset will be 0x0c + some bytes
+ - AbbrCode: 0x00000002
+ Values:
+ - Value: 0x0000000000000000 # DW_AT_name -> "callee"
+ - Value: 0x0000000000003000 # DW_AT_low_pc
+ - Value: 0x0000000000000010 # DW_AT_high_pc
+ # DW_TAG_subprogram (caller, with DW_AT_call_all_calls)
+ - AbbrCode: 0x00000003
+ Values:
+ - Value: 0x0000000000000007 # DW_AT_name -> "caller"
+ - Value: 0x0000000000001000 # DW_AT_low_pc
+ - Value: 0x0000000000000100 # DW_AT_high_pc
+ # DW_TAG_lexical_block (child of caller)
+ - AbbrCode: 0x00000004
+ Values:
+ - Value: 0x0000000000001000 # DW_AT_low_pc
+ - Value: 0x0000000000000080 # DW_AT_high_pc
+ # DW_TAG_call_site (child of lexical_block)
+ - AbbrCode: 0x00000005
+ Values:
+ - Value: 0x0000000000000015 # DW_AT_call_origin -> callee subprogram
+ - AbbrCode: 0x00000000 # end lexical_block
+ Values: []
+ - AbbrCode: 0x00000000 # end caller subprogram
+ Values: []
+ - AbbrCode: 0x00000000 # end compile_unit
+ Values: []
+...
``````````
</details>
https://github.com/llvm/llvm-project/pull/186413
More information about the llvm-commits
mailing list