[llvm] df6d057 - Fix a crash in DWARFUnit::getInlinedChainForAddress in case of unexpected DWARF information.
Alex Orlov via llvm-commits
llvm-commits at lists.llvm.org
Tue Mar 9 02:21:31 PST 2021
Author: Alex Orlov
Date: 2021-03-09T14:20:27+04:00
New Revision: df6d0579e18e868ef4b6e97794eacd5af86e1b8a
URL: https://github.com/llvm/llvm-project/commit/df6d0579e18e868ef4b6e97794eacd5af86e1b8a
DIFF: https://github.com/llvm/llvm-project/commit/df6d0579e18e868ef4b6e97794eacd5af86e1b8a.diff
LOG: Fix a crash in DWARFUnit::getInlinedChainForAddress in case of unexpected DWARF information.
In some cases a broken or invalid debug info could cause a crash in DWARFUnit::getInlinedChainForAddress during parsing a chain of in-lined functions. This patch fixes this issue.
Reviewed By: dblaikie
Differential Revision: https://reviews.llvm.org/D98119
Added:
llvm/test/DebugInfo/invalid-inlined-subroutine.s
Modified:
llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
Removed:
################################################################################
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
index 8493950a29b2..d0432345b8d1 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
@@ -688,15 +688,15 @@ DWARFUnit::getInlinedChainForAddress(uint64_t Address,
DWARFDie SubroutineDIE =
(DWO ? *DWO : *this).getSubroutineForAddress(Address);
- if (!SubroutineDIE)
- return;
-
- while (!SubroutineDIE.isSubprogramDIE()) {
+ while (SubroutineDIE) {
+ if (SubroutineDIE.isSubprogramDIE()) {
+ InlinedChain.push_back(SubroutineDIE);
+ return;
+ }
if (SubroutineDIE.getTag() == DW_TAG_inlined_subroutine)
InlinedChain.push_back(SubroutineDIE);
SubroutineDIE = SubroutineDIE.getParent();
}
- InlinedChain.push_back(SubroutineDIE);
}
const DWARFUnitIndex &llvm::getDWARFUnitIndex(DWARFContext &Context,
diff --git a/llvm/test/DebugInfo/invalid-inlined-subroutine.s b/llvm/test/DebugInfo/invalid-inlined-subroutine.s
new file mode 100644
index 000000000000..06bb9d64a76c
--- /dev/null
+++ b/llvm/test/DebugInfo/invalid-inlined-subroutine.s
@@ -0,0 +1,145 @@
+## This test checks how we handle parsing a broken DWARF when
+## a parent of DW_TAG_inlined_subroutine is anything other than DW_TAG_subprogram.
+
+# REQUIRES: x86-registered-target
+
+# RUN: llvm-mc -filetype=obj -triple=i386-linux-gnu -o %t.o %s
+# RUN: llvm-symbolizer "CODE %t.o 0" \
+# RUN: | FileCheck %s --strict-whitespace --match-full-lines --implicit-check-not={{.}}
+
+# CHECK:main
+# CHECK-NEXT:/tmp/test{{/|\\}}test.cpp:2:3
+
+## Generated from:
+##
+## int main() {
+## return 123;
+## }
+##
+## clang++ --target=i386-linux-gnu test.cpp -g -O2 -std=c++11 -S -o test.s
+
+ .text
+ .file "test.cpp"
+ .globl main # -- Begin function main
+ .p2align 4, 0x90
+ .type main, at function
+main: # @main
+.Lfunc_begin0:
+ .file 1 "/tmp/test" "test.cpp"
+ .loc 1 1 0 # test.cpp:1:0
+ .cfi_sections .debug_frame
+ .cfi_startproc
+# %bb.0: # %entry
+ .loc 1 2 3 prologue_end # test.cpp:2:3
+ movl $123, %eax
+ retl
+.Ltmp0:
+.Lfunc_end0:
+ .size main, .Lfunc_end0-main
+ .cfi_endproc
+ # -- End function
+ .section .debug_abbrev,"", at progbits
+ .byte 1 # Abbreviation Code
+ .byte 17 # DW_TAG_compile_unit
+ .byte 1 # DW_CHILDREN_yes
+ .byte 37 # DW_AT_producer
+ .byte 14 # DW_FORM_strp
+ .byte 19 # DW_AT_language
+ .byte 5 # DW_FORM_data2
+ .byte 3 # DW_AT_name
+ .byte 14 # DW_FORM_strp
+ .byte 16 # DW_AT_stmt_list
+ .byte 23 # DW_FORM_sec_offset
+ .byte 27 # DW_AT_comp_dir
+ .byte 14 # DW_FORM_strp
+ .byte 17 # DW_AT_low_pc
+ .byte 1 # DW_FORM_addr
+ .byte 18 # DW_AT_high_pc
+ .byte 6 # DW_FORM_data4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 2 # Abbreviation Code
+// Replace DW_TAG_subprogram with DW_TAG_inlined_subroutine
+// .byte 46 # DW_TAG_subprogram
+ .byte 29 # DW_TAG_inlined_subroutine
+ .byte 0 # DW_CHILDREN_no
+ .byte 17 # DW_AT_low_pc
+ .byte 1 # DW_FORM_addr
+ .byte 18 # DW_AT_high_pc
+ .byte 6 # DW_FORM_data4
+ .byte 64 # DW_AT_frame_base
+ .byte 24 # DW_FORM_exprloc
+ .ascii "\227B" # DW_AT_GNU_all_call_sites
+ .byte 25 # DW_FORM_flag_present
+ .byte 3 # DW_AT_name
+ .byte 14 # DW_FORM_strp
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 63 # DW_AT_external
+ .byte 25 # DW_FORM_flag_present
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 3 # Abbreviation Code
+ .byte 36 # DW_TAG_base_type
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .byte 14 # DW_FORM_strp
+ .byte 62 # DW_AT_encoding
+ .byte 11 # DW_FORM_data1
+ .byte 11 # DW_AT_byte_size
+ .byte 11 # DW_FORM_data1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 0 # EOM(3)
+ .section .debug_info,"", at progbits
+.Lcu_begin0:
+ .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
+.Ldebug_info_start0:
+ .short 4 # DWARF version number
+ .long .debug_abbrev # Offset Into Abbrev. Section
+ .byte 4 # Address Size (in bytes)
+ .byte 1 # Abbrev [1] 0xb:0x38 DW_TAG_compile_unit
+ .long .Linfo_string0 # DW_AT_producer
+ .short 26 # DW_AT_language
+ .long .Linfo_string1 # DW_AT_name
+ .long .Lline_table_start0 # DW_AT_stmt_list
+ .long .Linfo_string2 # DW_AT_comp_dir
+ .long .Lfunc_begin0 # DW_AT_low_pc
+ .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
+ .byte 2 # Abbrev [2] 0x26:0x15 DW_TAG_subprogram
+ .long .Lfunc_begin0 # DW_AT_low_pc
+ .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
+ .byte 1 # DW_AT_frame_base
+ .byte 84
+ # DW_AT_GNU_all_call_sites
+ .long .Linfo_string3 # DW_AT_name
+ .byte 1 # DW_AT_decl_file
+ .byte 1 # DW_AT_decl_line
+ .long 59 # DW_AT_type
+ # DW_AT_external
+ .byte 3 # Abbrev [3] 0x3b:0x7 DW_TAG_base_type
+ .long .Linfo_string4 # DW_AT_name
+ .byte 5 # DW_AT_encoding
+ .byte 4 # DW_AT_byte_size
+ .byte 0 # End Of Children Mark
+.Ldebug_info_end0:
+ .section .debug_str,"MS", at progbits,1
+.Linfo_string0:
+ .asciz "clang version 13.0.0"
+.Linfo_string1:
+ .asciz "test.cpp"
+.Linfo_string2:
+ .asciz "/tmp/test" # string offset=114
+.Linfo_string3:
+ .asciz "main"
+.Linfo_string4:
+ .asciz "int"
+ .ident "clang version 13.0.0"
+ .section ".note.GNU-stack","", at progbits
+ .addrsig
+ .section .debug_line,"", at progbits
+.Lline_table_start0:
More information about the llvm-commits
mailing list