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

Reply via email to