Skip to content

Commit 3525bc6

Browse files
[llvm-debuginfo-analyzer] Fix crash with WebAssembly dead code
#136772 Incorrect handling of 'tombstone' value for WebAssembly. Address reviewes comments: - Make 'tombstone' a member of 'LVDWARFReader', to eliminate the extra dependency on the CodeView reader. - Rename the test case and rework some comments to make it easy to understand.
1 parent 6eca31c commit 3525bc6

File tree

4 files changed

+22
-45
lines changed

4 files changed

+22
-45
lines changed

llvm/include/llvm/DebugInfo/LogicalView/Core/LVReader.h

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -156,9 +156,6 @@ class LLVM_ABI LVReader {
156156
LVAddress LowerAddress, LVAddress UpperAddress);
157157
LVRange *getSectionRanges(LVSectionIndex SectionIndex);
158158

159-
// The value is updated for each Compile Unit that is processed.
160-
std::optional<LVAddress> TombstoneAddress;
161-
162159
// Record Compilation Unit entry.
163160
void addCompileUnitOffset(LVOffset Offset, LVScopeCompileUnit *CompileUnit) {
164161
CompileUnits.emplace(Offset, CompileUnit);
@@ -285,12 +282,6 @@ class LLVM_ABI LVReader {
285282
return CompileUnit->getCPUType();
286283
}
287284

288-
void setTombstoneAddress(LVAddress Address) { TombstoneAddress = Address; }
289-
LVAddress getTombstoneAddress() const {
290-
assert(TombstoneAddress && "Unset tombstone value");
291-
return TombstoneAddress.value();
292-
}
293-
294285
// Access to the scopes root.
295286
LVScopeRoot *getScopesRoot() const { return Root; }
296287

llvm/include/llvm/DebugInfo/LogicalView/Readers/LVCodeViewReader.h

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -193,17 +193,11 @@ class LVCodeViewReader final : public LVBinaryReader {
193193
llvm::object::COFFObjectFile &Obj, ScopedPrinter &W,
194194
StringRef ExePath)
195195
: LVBinaryReader(Filename, FileFormatName, W, LVBinaryType::COFF),
196-
Input(&Obj), ExePath(ExePath), LogicalVisitor(this, W, Input) {
197-
// CodeView does not have the concept of 'tombstone' address.
198-
setTombstoneAddress(MaxAddress);
199-
}
196+
Input(&Obj), ExePath(ExePath), LogicalVisitor(this, W, Input) {}
200197
LVCodeViewReader(StringRef Filename, StringRef FileFormatName,
201198
llvm::pdb::PDBFile &Pdb, ScopedPrinter &W, StringRef ExePath)
202199
: LVBinaryReader(Filename, FileFormatName, W, LVBinaryType::COFF),
203-
Input(&Pdb), ExePath(ExePath), LogicalVisitor(this, W, Input) {
204-
// CodeView does not have the concept of 'tombstone' address.
205-
setTombstoneAddress(MaxAddress);
206-
}
200+
Input(&Pdb), ExePath(ExePath), LogicalVisitor(this, W, Input) {}
207201
LVCodeViewReader(const LVCodeViewReader &) = delete;
208202
LVCodeViewReader &operator=(const LVCodeViewReader &) = delete;
209203
~LVCodeViewReader() = default;

llvm/include/llvm/DebugInfo/LogicalView/Readers/LVDWARFReader.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ class LVDWARFReader final : public LVBinaryReader {
5858
bool FoundLowPC = false;
5959
bool FoundHighPC = false;
6060

61+
// The value is updated for each Compile Unit that is processed.
62+
std::optional<LVAddress> TombstoneAddress;
63+
6164
// Cross references (Elements).
6265
using LVElementSet = std::unordered_set<LVElement *>;
6366
struct LVElementEntry {
@@ -127,6 +130,12 @@ class LVDWARFReader final : public LVBinaryReader {
127130
LVAddress getCUHighAddress() const { return CUHighAddress; }
128131
void setCUHighAddress(LVAddress Address) { CUHighAddress = Address; }
129132

133+
void setTombstoneAddress(LVAddress Address) { TombstoneAddress = Address; }
134+
LVAddress getTombstoneAddress() const {
135+
assert(TombstoneAddress && "Unset tombstone value");
136+
return TombstoneAddress.value();
137+
}
138+
130139
const LVSymbols &GetSymbolsWithLocations() const {
131140
return SymbolsWithLocations;
132141
}

llvm/test/tools/llvm-debuginfo-analyzer/WebAssembly/wasm-crash-tombstone.s renamed to llvm/test/tools/llvm-debuginfo-analyzer/WebAssembly/wasm-32bit-tombstone.s

Lines changed: 11 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,7 @@
11
# REQUIRES: x86-registered-target
22

3-
# llvm-debuginfo-analyzer crashes on dead code
4-
# https://github.com/llvm/llvm-project/issues/136772
5-
6-
# For the attached reproducer:
7-
# llvm-dwarfdump out/lzma-lzmadec.wasm --all
8-
#
9-
# shows:
10-
#
11-
# 0x000002b3: DW_TAG_subprogram
12-
# DW_AT_low_pc (dead code)
13-
# DW_AT_high_pc (0x00000362)
14-
# DW_AT_frame_base (DW_OP_WASM_location 0x0 0x6, DW_OP_stack_value)
15-
16-
# llvm-debuginfo-analyzer out/lzma-lzmadec.wasm --print=instructions
17-
#
18-
# crashes and shows a stack dump:
19-
#
20-
# PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/
21-
# and include the crash backtrace.
22-
# Stack dump:
23-
# 0. Program arguments: llvm-debuginfo-analyzer out/lzma-lzmadec.wasm --print=instructions
3+
# Test that DWARF tombstones are correctly detected/respected in wasm
4+
# 32 bit object files.
245

256
# The test case was produced by the following steps:
267
#
@@ -29,8 +10,10 @@
2910
# }
3011
#
3112
# 1) clang --target=wasm32 -S -g test-clang.cpp
32-
# -o Inputs/wasm-crash-tombstone.s
33-
# 2) Manually changing the DW_AT_low_pc for the DW_TAG_subprogram:
13+
# -o Inputs/wasm-32bit-tombstone.s
14+
#
15+
# 2) Creating a single function, tombstoning it in the assembly, by
16+
# manually changing the DW_AT_low_pc for the DW_TAG_subprogram:
3417
# .Lfunc_begin0 to 0xffffffff to mark the function as dead code:
3518
#
3619
# .int8 2 # Abbrev [2] 0x26:0x1b DW_TAG_subprogram
@@ -42,21 +25,21 @@
4225
# .int32 .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
4326

4427
# RUN: llvm-mc -arch=wasm32 -filetype=obj \
45-
# RUN: %p/wasm-crash-tombstone.s \
46-
# RUN: -o %t.wasm-crash-tombstone.wasm
28+
# RUN: %p/wasm-32bit-tombstone.s \
29+
# RUN: -o %t.wasm-32bit-tombstone.wasm
4730

4831
# RUN: llvm-debuginfo-analyzer --select-elements=Discarded \
4932
# RUN: --print=elements \
50-
# RUN: %t.wasm-crash-tombstone.wasm 2>&1 | \
33+
# RUN: %t.wasm-32bit-tombstone.wasm 2>&1 | \
5134
# RUN: FileCheck --strict-whitespace -check-prefix=ONE %s
5235

5336
# ONE: Logical View:
54-
# ONE-NEXT: {File} '{{.*}}wasm-crash-tombstone.wasm'
37+
# ONE-NEXT: {File} '{{.*}}wasm-32bit-tombstone.wasm'
5538
# ONE-EMPTY:
5639
# ONE-NEXT: {CompileUnit} 'test-clang.cpp'
5740
# ONE-NEXT: {Function} not_inlined 'foo' -> 'void'
5841

59-
# RUN: llvm-dwarfdump --debug-info %t.wasm-crash-tombstone.wasm | \
42+
# RUN: llvm-dwarfdump --debug-info %t.wasm-32bit-tombstone.wasm | \
6043
# RUN: FileCheck %s --check-prefix=TWO
6144

6245
# TWO: DW_TAG_subprogram

0 commit comments

Comments
 (0)