-
Notifications
You must be signed in to change notification settings - Fork 14.1k
[llvm-debuginfo-analyzer] Fix crash with WebAssembly dead code #141616
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?
Changes from all commits
4d1a2eb
036b1e6
ab09f83
a563faa
a93d7f6
6eca31c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
# REQUIRES: x86-registered-target | ||
|
||
# llvm-debuginfo-analyzer crashes on dead code | ||
# https://github.com/llvm/llvm-project/issues/136772 | ||
|
||
# For the attached reproducer: | ||
# llvm-dwarfdump out/lzma-lzmadec.wasm --all | ||
# | ||
# shows: | ||
# | ||
# 0x000002b3: DW_TAG_subprogram | ||
# DW_AT_low_pc (dead code) | ||
# DW_AT_high_pc (0x00000362) | ||
# DW_AT_frame_base (DW_OP_WASM_location 0x0 0x6, DW_OP_stack_value) | ||
|
||
# llvm-debuginfo-analyzer out/lzma-lzmadec.wasm --print=instructions | ||
# | ||
# crashes and shows a stack dump: | ||
# | ||
# PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ | ||
# and include the crash backtrace. | ||
# Stack dump: | ||
# 0. Program arguments: llvm-debuginfo-analyzer out/lzma-lzmadec.wasm --print=instructions | ||
|
||
Comment on lines
+6
to
+24
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This commentary, and the name of the test file are probably not suitable/may be confusing - they describe the state of the world before this patch, and in somewhat vague terms "this complex test causes this thing to crash" rather than the specific issue it's been debugged down to. Something more like "wasm-32bit-tombstone" might be a more suitable title, and a sentence describing "test that DWARF tombstones are correctly detected/respected in wasm 32 bit object files"? (& then proceed to describe the test case as done below - creating a single function, tombstoning it in the assembly, etc) |
||
# The test case was produced by the following steps: | ||
# | ||
# // test-clang.cpp | ||
# void foo() { | ||
# } | ||
# | ||
# 1) clang --target=wasm32 -S -g test-clang.cpp | ||
# -o Inputs/wasm-crash-tombstone.s | ||
# 2) Manually changing the DW_AT_low_pc for the DW_TAG_subprogram: | ||
# .Lfunc_begin0 to 0xffffffff to mark the function as dead code: | ||
# | ||
# .int8 2 # Abbrev [2] 0x26:0x1b DW_TAG_subprogram | ||
# .int32 .Lfunc_begin0 # DW_AT_low_pc <--------- | ||
# .int32 .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc | ||
|
||
# .int8 2 # Abbrev [2] 0x26:0x1b DW_TAG_subprogram | ||
# .int32 0xffffffff # DW_AT_low_pc <--------- | ||
# .int32 .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc | ||
|
||
# RUN: llvm-mc -arch=wasm32 -filetype=obj \ | ||
# RUN: %p/wasm-crash-tombstone.s \ | ||
# RUN: -o %t.wasm-crash-tombstone.wasm | ||
|
||
# RUN: llvm-debuginfo-analyzer --select-elements=Discarded \ | ||
# RUN: --print=elements \ | ||
# RUN: %t.wasm-crash-tombstone.wasm 2>&1 | \ | ||
# RUN: FileCheck --strict-whitespace -check-prefix=ONE %s | ||
|
||
# ONE: Logical View: | ||
# ONE-NEXT: {File} '{{.*}}wasm-crash-tombstone.wasm' | ||
# ONE-EMPTY: | ||
# ONE-NEXT: {CompileUnit} 'test-clang.cpp' | ||
# ONE-NEXT: {Function} not_inlined 'foo' -> 'void' | ||
|
||
# RUN: llvm-dwarfdump --debug-info %t.wasm-crash-tombstone.wasm | \ | ||
# RUN: FileCheck %s --check-prefix=TWO | ||
|
||
# TWO: DW_TAG_subprogram | ||
# TWO-NEXT: DW_AT_low_pc (dead code) | ||
# TWO-NEXT: DW_AT_high_pc | ||
# TWO-NEXT: DW_AT_name ("foo") | ||
|
||
.text | ||
.file "test-clang.cpp" | ||
.functype _Z3foov () -> () | ||
.section .text._Z3foov,"",@ | ||
_Z3foov: # @_Z3foov | ||
.Lfunc_begin0: | ||
.functype _Z3foov () -> () | ||
return | ||
end_function | ||
.Lfunc_end0: | ||
# -- End function | ||
.section .debug_abbrev,"",@ | ||
.int8 1 # Abbreviation Code | ||
.int8 17 # DW_TAG_compile_unit | ||
.int8 1 # DW_CHILDREN_yes | ||
.int8 3 # DW_AT_name | ||
.int8 14 # DW_FORM_strp | ||
.int8 17 # DW_AT_low_pc | ||
.int8 1 # DW_FORM_addr | ||
.int8 18 # DW_AT_high_pc | ||
.int8 6 # DW_FORM_data4 | ||
.int8 0 # EOM(1) | ||
.int8 0 # EOM(2) | ||
.int8 2 # Abbreviation Code | ||
.int8 46 # DW_TAG_subprogram | ||
.int8 0 # DW_CHILDREN_no | ||
.int8 17 # DW_AT_low_pc | ||
.int8 1 # DW_FORM_addr | ||
.int8 18 # DW_AT_high_pc | ||
.int8 6 # DW_FORM_data4 | ||
.int8 3 # DW_AT_name | ||
.int8 14 # DW_FORM_strp | ||
.int8 0 # EOM(1) | ||
.int8 0 # EOM(2) | ||
.int8 0 # EOM(3) | ||
.section .debug_info,"",@ | ||
.Lcu_begin0: | ||
.int32 .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit | ||
.Ldebug_info_start0: | ||
.int16 4 # DWARF version number | ||
.int32 .debug_abbrev0 # Offset Into Abbrev. Section | ||
.int8 4 # Address Size (in bytes) | ||
.int8 1 # Abbrev [1] 0xb:0x37 DW_TAG_compile_unit | ||
.int32 .Linfo_string1 # DW_AT_name | ||
.int32 .Lfunc_begin0 # DW_AT_low_pc | ||
.int32 .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc | ||
.int8 2 # Abbrev [2] 0x26:0x1b DW_TAG_subprogram | ||
.int32 0xffffffff # DW_AT_low_pc | ||
.int32 .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc | ||
.int32 .Linfo_string4 # DW_AT_name | ||
.int8 0 # End Of Children Mark | ||
.Ldebug_info_end0: | ||
.section .debug_str,"S",@ | ||
.Linfo_string1: | ||
.asciz "test-clang.cpp" # string offset=176 | ||
.Linfo_string4: | ||
.asciz "foo" # string offset=241 | ||
.ident "clang version 19.0.0" |
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.
Comment could be a bit more descriptive about why we then set the tombstone to maxaddress - even though CV doesn't have a tombstone?
But my suspicion/theory is that perhaps we can leave this unset? Or further - why is the tombstone a member of the LVReader - could it be only a member of the LVDWARFReader? It's the only one that sets or gets the value?