https://github.com/JDevlieghere updated https://github.com/llvm/llvm-project/pull/205691
>From b04b9fb20548ae93ddaef108026c54ad873ccfd2 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere <[email protected]> Date: Wed, 24 Jun 2026 15:34:35 -0700 Subject: [PATCH] [lldb] Don't create functions for DWARF dead-code tombstones A function the linker eliminated (dead-stripped, or inlined into all its callers) keeps a DWARF subprogram DIE whose DW_AT_low_pc is a "(dead code)" tombstone: the all-ones value for the unit's address size. LLDB has no explicit tombstone check; it only rejects dead code where Address::IsValid() happens to catch it, i.e. when the tombstone equals the 8-byte LLDB_INVALID_ADDRESS. On wasm32 the tombstone is the 4-byte 0xffffffff, which IsValid() lets through, so LLDB builds a section-less, module-less lldb_private::Function and later crashes in Block::GetRangeContainingAddress (reached from Function::GetPrologueByteSize) dereferencing the empty module. Require the low PC to resolve to a section in SymbolFileDWARF::ParseFunction, using Address::IsSectionOffset() instead of IsValid(). This is the single point where functions are created, so it covers both the DW_AT_low/high_pc and DW_AT_ranges encodings, and it rejects any low PC that doesn't land in real code regardless of address width. It also avoids special-casing the all- ones tombstone value, which is an LLVM convention; other linkers tombstone with zero or a near-zero address, and those are already handled by the adjacent range.valid()/m_first_code_address check. --- .../SymbolFile/DWARF/SymbolFileDWARF.cpp | 5 +- .../DWARF/Inputs/gnu-ref-strp-alt.yaml | 7 ++ .../SymbolFile/DWARF/gnu-ref-strp-alt.test | 2 +- .../wasm-dead-code-function-breakpoint.yaml | 78 +++++++++++++++++++ 4 files changed, 90 insertions(+), 2 deletions(-) create mode 100644 lldb/test/Shell/SymbolFile/DWARF/wasm-dead-code-function-breakpoint.yaml diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index 56fbf3fd771b5..5f629e90f006d 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -926,8 +926,11 @@ Function *SymbolFileDWARF::ParseFunction(CompileUnit &comp_unit, for (const auto &range : *die_ranges) { if (range.valid() && range.LowPC < m_first_code_address) continue; + // Require the low PC to resolve to a section. This rejects addresses that + // don't correspond to any real code, such as the "(dead code)" tombstone + // a linker leaves on the DW_AT_low_pc of an eliminated function. if (Address base_addr(range.LowPC, module_sp->GetSectionList()); - base_addr.IsValid() && FixupAddress(base_addr)) + base_addr.IsSectionOffset() && FixupAddress(base_addr)) ranges.emplace_back(std::move(base_addr), range.HighPC - range.LowPC); } } else { diff --git a/lldb/test/Shell/SymbolFile/DWARF/Inputs/gnu-ref-strp-alt.yaml b/lldb/test/Shell/SymbolFile/DWARF/Inputs/gnu-ref-strp-alt.yaml index f4fb7d6d7c369..88752a40c03a0 100644 --- a/lldb/test/Shell/SymbolFile/DWARF/Inputs/gnu-ref-strp-alt.yaml +++ b/lldb/test/Shell/SymbolFile/DWARF/Inputs/gnu-ref-strp-alt.yaml @@ -5,6 +5,13 @@ FileHeader: Type: ET_DYN Machine: EM_X86_64 Entry: 0x1000 +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x1000 + AddressAlign: 0x10 + Size: 0x100 DWARF: debug_str: - '' diff --git a/lldb/test/Shell/SymbolFile/DWARF/gnu-ref-strp-alt.test b/lldb/test/Shell/SymbolFile/DWARF/gnu-ref-strp-alt.test index c81c41a8b5fab..150fe16327268 100644 --- a/lldb/test/Shell/SymbolFile/DWARF/gnu-ref-strp-alt.test +++ b/lldb/test/Shell/SymbolFile/DWARF/gnu-ref-strp-alt.test @@ -9,4 +9,4 @@ # CHECK: (lldb) b bar # CHECK-NOT: unsupported DW_FORM values: -# CHECK: Breakpoint 1: address = 0x0000000000001000 +# CHECK: Breakpoint 1: {{.*}}address = 0x0000000000001000 diff --git a/lldb/test/Shell/SymbolFile/DWARF/wasm-dead-code-function-breakpoint.yaml b/lldb/test/Shell/SymbolFile/DWARF/wasm-dead-code-function-breakpoint.yaml new file mode 100644 index 0000000000000..fb7f7d0f062ec --- /dev/null +++ b/lldb/test/Shell/SymbolFile/DWARF/wasm-dead-code-function-breakpoint.yaml @@ -0,0 +1,78 @@ +# A function the linker eliminated (dead-stripped, or inlined into all its +# callers) keeps a DWARF subprogram DIE whose DW_AT_low_pc is a "(dead code)" +# tombstone. Such a tombstone resolves to no section, meaning the DIE doesn't +# describe real code, and hence shouldn't resolve to a breakpoint. + +# RUN: yaml2obj %s -o %t +# RUN: %lldb %t -o "breakpoint set --name dead_stripped" \ +# RUN: -o "breakpoint set --name live" -o exit 2>&1 | FileCheck %s + +# CHECK: (lldb) breakpoint set --name dead_stripped +# CHECK-NEXT: Breakpoint 1: no locations (pending). +# CHECK: (lldb) breakpoint set --name live +# CHECK-NEXT: Breakpoint 2: where = {{.*}}`live{{.*}}, address = 0x00000017 + +--- !WASM +FileHeader: + Version: 0x1 +Sections: + - Type: TYPE + Signatures: + - Index: 0 + ParamTypes: + - I32 + ReturnTypes: + - I32 + - Type: FUNCTION + FunctionTypes: [ 0 ] + - Type: MEMORY + Memories: + - Minimum: 0x1 + - Type: GLOBAL + Globals: + - Index: 0 + Type: I32 + Mutable: true + InitExpr: + Opcode: I32_CONST + Value: 65536 + - Type: EXPORT + Exports: + - Name: memory + Kind: MEMORY + Index: 0 + - Name: live + Kind: FUNCTION + Index: 0 + - Type: CODE + Functions: + - Index: 0 + Locals: + - Type: I32 + Count: 1 + Body: 23808080800041106B21012001200036020C200128020C4101740F0B + - Type: CUSTOM + Name: .debug_abbrev + Payload: 011101250E1305030E10171B0E110155170000022E01110112064018030E3A0B3B0B271949133F1900000305000218030E3A0B3B0B49130000042400030E3E0B0B0B000000 + - Type: CUSTOM + HeaderSecSizeEncodingLen: 2 + Name: .debug_info + Payload: 780000000400000000000401290000001D001E0000000000000006000000000000000000000002FFFFFFFF1F00000004ED00019F100000000101740000000302910C000000000101740000000002020000001F00000004ED00019F0B0000000102740000000302910C00000000010274000000000402000000050400 + - Type: CUSTOM + Name: .debug_ranges + Payload: FEFFFFFFFEFFFFFF02000000210000000000000000000000 + - Type: CUSTOM + Name: .debug_str + Payload: 7800696E74002F746D70006C69766500646561645F7374726970706564002F746D702F6D696E2E6300636C616E672076657273696F6E2032322E312E302D776173692D73646B202868747470733A2F2F6769746875622E636F6D2F6C6C766D2F6C6C766D2D70726F6A65637420343433346461626236393931363835366238323466363861363462303239633637313735653533322900 + - Type: CUSTOM + Name: .debug_line + Payload: 5500000004001D000000010101FB0E0D000101010100000001000001006D696E2E630000000000000502FFFFFFFF0105230A084A05250658051C3C02020001010005020200000013051A0A084A051C065805133C0202000101 + - Type: CUSTOM + Name: name + FunctionNames: + - Index: 0 + Name: live + GlobalNames: + - Index: 0 + Name: __stack_pointer +... _______________________________________________ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
