Skip to content

Conversation

DataCorrupted
Copy link
Member

@DataCorrupted DataCorrupted commented Sep 8, 2025

Context

#99710 introduced .loc_label so we can terminate a line sequence. However, it did not advance PC properly. This is problematic for 1-instruction functions as it will have zero-length sequence. The test checked in that PR shows the problem:

# CHECK-LINE-TABLE:                  Address            Line   Column File   ISA Discriminator OpIndex Flags
# CHECK-LINE-TABLE-NEXT:             ------------------ ------ ------ ------ --- ------------- ------- -------------
# CHECK-LINE-TABLE-NEXT: 0x00000028: 05 DW_LNS_set_column (1)
# CHECK-LINE-TABLE-NEXT: 0x0000002a: 00 DW_LNE_set_address (0x0000000000000000)
# CHECK-LINE-TABLE-NEXT: 0x00000035: 01 DW_LNS_copy
# CHECK-LINE-TABLE-NEXT:             0x0000000000000000      1      1      1   0             0       0  is_stmt
# CHECK-LINE-TABLE-NEXT: 0x00000036: 00 DW_LNE_end_sequence
# CHECK-LINE-TABLE-NEXT:             0x0000000000000000      1      1      1   0             0       0  is_stmt end_sequence

Both rows having PC 0x0 is incorrect, and parsers won't be able to parse them. See more explanation why this is wrong in #154851.

Design

This PR attempts to fix this by advancing the PC to the next available Label, and advance to the end of the section if no Label is available.

Implementation

  • emitDwarfLineEndEntry will advance PC to the CurrLabel
  • If CurrLabel is null, its probably a fake LineEntry we introduced in [DebugInfo][DWARF] Emit Per-Function Line Table Offsets and End Sequences #110192. In that case look for the next Label
  • If still not label can be found, use null and emitDwarfLineEndEntry is smart enough to advance PC to the end of the section
  • Rename LastLabel to PrevLabel, "last" can mean "previous" or "final", this is ambigous.
  • Updated the tests to emit a correct label.

Note

This fix should render #154986 and #154851 obsolete, they were temporary fixes and don't resolve the root cause.

@llvmbot
Copy link
Member

llvmbot commented Sep 8, 2025

@llvm/pr-subscribers-debuginfo

@llvm/pr-subscribers-llvm-mc

Author: Peter Rong (DataCorrupted)

Changes

Context

#99710 introduced .loc_label so we can terminate a line sequence. However, it did not advance PC properly. This is problematic for 1-instruction functions as it will have zero-length sequence. The test checked in that PR shows the problem:

# CHECK-LINE-TABLE:                  Address            Line   Column File   ISA Discriminator OpIndex Flags
# CHECK-LINE-TABLE-NEXT:             ------------------ ------ ------ ------ --- ------------- ------- -------------
# CHECK-LINE-TABLE-NEXT: 0x00000028: 05 DW_LNS_set_column (1)
# CHECK-LINE-TABLE-NEXT: 0x0000002a: 00 DW_LNE_set_address (0x0000000000000000)
# CHECK-LINE-TABLE-NEXT: 0x00000035: 01 DW_LNS_copy
# CHECK-LINE-TABLE-NEXT:             0x0000000000000000      1      1      1   0             0       0  is_stmt
# CHECK-LINE-TABLE-NEXT: 0x00000036: 00 DW_LNE_end_sequence
# CHECK-LINE-TABLE-NEXT:             0x0000000000000000      1      1      1   0             0       0  is_stmt end_sequence

Both rows having PC 0x0 is incorrect, and parsers won't be able to parse them. See more explanation why this is wrong in #154851.

Fix

This PR attempts to fix this by advancing the PC to the next available Label, and advance to the end of the section if no Label is available.

Impl

  • emitDwarfLineEndEntry will advance PC to the CurrLabel
  • If CurrLabel is null, its probably a fake LineEntry we introduced in #110192. In that case look for the next Label
  • If still not label can be found, use null and emitDwarfLineEndEntry is smart enough to advance PC to the end of the section
  • Rename LastLabel to PrevLabel, "last" can mean "previous" or "final", this is ambigous.
  • Updated the tests to emit a correct label.

Note

This fix should render #154986 and #154851 obsolete, they were temporary fixes and don't resolve the root cause.


Full diff: https://github.com/llvm/llvm-project/pull/157529.diff

3 Files Affected:

  • (modified) llvm/lib/MC/MCDwarf.cpp (+20-10)
  • (modified) llvm/test/DebugInfo/X86/DW_AT_LLVM_stmt_seq_sec_offset.ll (+30-29)
  • (modified) llvm/test/MC/ELF/debug-loc-label.s (+29-25)
diff --git a/llvm/lib/MC/MCDwarf.cpp b/llvm/lib/MC/MCDwarf.cpp
index e7c0d37e8f99b..e8f000a584839 100644
--- a/llvm/lib/MC/MCDwarf.cpp
+++ b/llvm/lib/MC/MCDwarf.cpp
@@ -181,7 +181,7 @@ void MCDwarfLineTable::emitOne(
 
   unsigned FileNum, LastLine, Column, Flags, Isa, Discriminator;
   bool IsAtStartSeq;
-  MCSymbol *LastLabel;
+  MCSymbol *PrevLabel;
   auto init = [&]() {
     FileNum = 1;
     LastLine = 1;
@@ -189,21 +189,31 @@ void MCDwarfLineTable::emitOne(
     Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0;
     Isa = 0;
     Discriminator = 0;
-    LastLabel = nullptr;
+    PrevLabel = nullptr;
     IsAtStartSeq = true;
   };
   init();
 
   // Loop through each MCDwarfLineEntry and encode the dwarf line number table.
   bool EndEntryEmitted = false;
-  for (const MCDwarfLineEntry &LineEntry : LineEntries) {
-    MCSymbol *Label = LineEntry.getLabel();
+  for (auto It = LineEntries.begin(); It != LineEntries.end(); ++It) {
+    auto LineEntry = *It;
+    MCSymbol *CurrLabel = LineEntry.getLabel();
     const MCAsmInfo *asmInfo = MCOS->getContext().getAsmInfo();
 
     if (LineEntry.LineStreamLabel) {
       if (!IsAtStartSeq) {
-        MCOS->emitDwarfLineEndEntry(Section, LastLabel,
-                                    /*EndLabel =*/LastLabel);
+        auto *Label = CurrLabel;
+        auto NextIt = It + 1;
+        // LineEntry with a null Label is probably a fake LineEntry we added
+        // when `-emit-func-debug-line-table-offsets` in order to terminate the
+        // sequence. Look for the next Label if possible, otherwise we will set
+        // the PC to the end of the section.
+        if (!Label && NextIt != LineEntries.end()) {
+          Label = NextIt->getLabel();
+        }
+        MCOS->emitDwarfLineEndEntry(Section, PrevLabel,
+                                    /*EndLabel =*/Label);
         init();
       }
       MCOS->emitLabel(LineEntry.LineStreamLabel, LineEntry.StreamLabelDefLoc);
@@ -211,7 +221,7 @@ void MCDwarfLineTable::emitOne(
     }
 
     if (LineEntry.IsEndEntry) {
-      MCOS->emitDwarfAdvanceLineAddr(INT64_MAX, LastLabel, Label,
+      MCOS->emitDwarfAdvanceLineAddr(INT64_MAX, PrevLabel, CurrLabel,
                                      asmInfo->getCodePointerSize());
       init();
       EndEntryEmitted = true;
@@ -258,12 +268,12 @@ void MCDwarfLineTable::emitOne(
     // At this point we want to emit/create the sequence to encode the delta in
     // line numbers and the increment of the address from the previous Label
     // and the current Label.
-    MCOS->emitDwarfAdvanceLineAddr(LineDelta, LastLabel, Label,
+    MCOS->emitDwarfAdvanceLineAddr(LineDelta, PrevLabel, CurrLabel,
                                    asmInfo->getCodePointerSize());
 
     Discriminator = 0;
     LastLine = LineEntry.getLine();
-    LastLabel = Label;
+    PrevLabel = CurrLabel;
     IsAtStartSeq = false;
   }
 
@@ -273,7 +283,7 @@ void MCDwarfLineTable::emitOne(
   // does not track ranges nor terminate the line table. In that case,
   // conservatively use the section end symbol to end the line table.
   if (!EndEntryEmitted && !IsAtStartSeq)
-    MCOS->emitDwarfLineEndEntry(Section, LastLabel);
+    MCOS->emitDwarfLineEndEntry(Section, PrevLabel);
 }
 
 void MCDwarfLineTable::endCurrentSeqAndEmitLineStreamLabel(MCStreamer *MCOS,
diff --git a/llvm/test/DebugInfo/X86/DW_AT_LLVM_stmt_seq_sec_offset.ll b/llvm/test/DebugInfo/X86/DW_AT_LLVM_stmt_seq_sec_offset.ll
index 58f6495924b90..10059b7b30c20 100644
--- a/llvm/test/DebugInfo/X86/DW_AT_LLVM_stmt_seq_sec_offset.ll
+++ b/llvm/test/DebugInfo/X86/DW_AT_LLVM_stmt_seq_sec_offset.ll
@@ -14,38 +14,39 @@
 ; STMT_SEQ:       DW_AT_LLVM_stmt_sequence [DW_FORM_sec_offset]	(0x00000043)
 ; STMT_SEQ:   DW_AT_name {{.*}}func01
 ; STMT_SEQ:   DW_TAG_subprogram [[[ABBREV_CODE2]]]
-; STMT_SEQ:       DW_AT_LLVM_stmt_sequence [DW_FORM_sec_offset]	(0x00000056)
+; STMT_SEQ:       DW_AT_LLVM_stmt_sequence [DW_FORM_sec_offset]	(0x00000058)
 ; STMT_SEQ:   DW_AT_name {{.*}}main
 
 ;; Check the entire line sequence to see that it's correct
-; STMT_SEQ:                   Address            Line   Column File   ISA Discriminator OpIndex Flags
-; STMT_SEQ-NEXT:              ------------------ ------ ------ ------ --- ------------- ------- -------------
-; STMT_SEQ-NEXT:  0x00000043: 04 DW_LNS_set_file (0)
-; STMT_SEQ-NEXT:  0x00000045: 05 DW_LNS_set_column (9)
-; STMT_SEQ-NEXT:  0x00000047: 0a DW_LNS_set_prologue_end
-; STMT_SEQ-NEXT:  0x00000048: 00 DW_LNE_set_address (0x00000000)
-; STMT_SEQ-NEXT:  0x0000004f: 16 address += 0,  line += 4,  op-index += 0
-; STMT_SEQ-NEXT:              0x0000000000000000      5      9      0   0             0       0  is_stmt prologue_end
-; STMT_SEQ-NEXT:  0x00000050: 05 DW_LNS_set_column (3)
-; STMT_SEQ-NEXT:  0x00000052: 67 address += 6,  line += 1,  op-index += 0
-; STMT_SEQ-NEXT:              0x0000000000000006      6      3      0   0             0       0  is_stmt
-; STMT_SEQ-NEXT:  0x00000053: 00 DW_LNE_end_sequence
-; STMT_SEQ-NEXT:              0x0000000000000006      6      3      0   0             0       0  is_stmt end_sequence
-; STMT_SEQ-NEXT:  0x00000056: 04 DW_LNS_set_file (0)
-; STMT_SEQ-NEXT:  0x00000058: 00 DW_LNE_set_address (0x00000008)
-; STMT_SEQ-NEXT:  0x0000005f: 03 DW_LNS_advance_line (10)
-; STMT_SEQ-NEXT:  0x00000061: 01 DW_LNS_copy
-; STMT_SEQ-NEXT:              0x0000000000000008     10      0      0   0             0       0  is_stmt
-; STMT_SEQ-NEXT:  0x00000062: 05 DW_LNS_set_column (10)
-; STMT_SEQ-NEXT:  0x00000064: 0a DW_LNS_set_prologue_end
-; STMT_SEQ-NEXT:  0x00000065: 83 address += 8,  line += 1,  op-index += 0
-; STMT_SEQ-NEXT:              0x0000000000000010     11     10      0   0             0       0  is_stmt prologue_end
-; STMT_SEQ-NEXT:  0x00000066: 05 DW_LNS_set_column (3)
-; STMT_SEQ-NEXT:  0x00000068: 9f address += 10,  line += 1,  op-index += 0
-; STMT_SEQ-NEXT:              0x000000000000001a     12      3      0   0             0       0  is_stmt
-; STMT_SEQ-NEXT:  0x00000069: 02 DW_LNS_advance_pc (addr += 5, op-index += 0)
-; STMT_SEQ-NEXT:  0x0000006b: 00 DW_LNE_end_sequence
-; STMT_SEQ-NEXT:              0x000000000000001f     12      3      0   0             0       0  is_stmt end_sequence
+; STMT_SEQ:                  Address            Line   Column File   ISA Discriminator OpIndex Flags
+; STMT_SEQ-NEXT:             ------------------ ------ ------ ------ --- ------------- ------- -------------
+; STMT_SEQ-NEXT: 0x00000043: 04 DW_LNS_set_file (0)
+; STMT_SEQ-NEXT: 0x00000045: 05 DW_LNS_set_column (9)
+; STMT_SEQ-NEXT: 0x00000047: 0a DW_LNS_set_prologue_end
+; STMT_SEQ-NEXT: 0x00000048: 00 DW_LNE_set_address (0x00000000)
+; STMT_SEQ-NEXT: 0x0000004f: 16 address += 0,  line += 4,  op-index += 0
+; STMT_SEQ-NEXT:             0x0000000000000000      5      9      0   0             0       0  is_stmt prologue_end
+; STMT_SEQ-NEXT: 0x00000050: 05 DW_LNS_set_column (3)
+; STMT_SEQ-NEXT: 0x00000052: 67 address += 6,  line += 1,  op-index += 0
+; STMT_SEQ-NEXT:             0x0000000000000006      6      3      0   0             0       0  is_stmt
+; STMT_SEQ-NEXT: 0x00000053: 02 DW_LNS_advance_pc (addr += 2, op-index += 0)
+; STMT_SEQ-NEXT: 0x00000055: 00 DW_LNE_end_sequence
+; STMT_SEQ-NEXT:             0x0000000000000008      6      3      0   0             0       0  is_stmt end_sequence
+; STMT_SEQ-NEXT: 0x00000058: 04 DW_LNS_set_file (0)
+; STMT_SEQ-NEXT: 0x0000005a: 00 DW_LNE_set_address (0x00000008)
+; STMT_SEQ-NEXT: 0x00000061: 03 DW_LNS_advance_line (10)
+; STMT_SEQ-NEXT: 0x00000063: 01 DW_LNS_copy
+; STMT_SEQ-NEXT:             0x0000000000000008     10      0      0   0             0       0  is_stmt
+; STMT_SEQ-NEXT: 0x00000064: 05 DW_LNS_set_column (10)
+; STMT_SEQ-NEXT: 0x00000066: 0a DW_LNS_set_prologue_end
+; STMT_SEQ-NEXT: 0x00000067: 83 address += 8,  line += 1,  op-index += 0
+; STMT_SEQ-NEXT:             0x0000000000000010     11     10      0   0             0       0  is_stmt prologue_end
+; STMT_SEQ-NEXT: 0x00000068: 05 DW_LNS_set_column (3)
+; STMT_SEQ-NEXT: 0x0000006a: 9f address += 10,  line += 1,  op-index += 0
+; STMT_SEQ-NEXT:             0x000000000000001a     12      3      0   0             0       0  is_stmt
+; STMT_SEQ-NEXT: 0x0000006b: 02 DW_LNS_advance_pc (addr += 5, op-index += 0)
+; STMT_SEQ-NEXT: 0x0000006d: 00 DW_LNE_end_sequence
+; STMT_SEQ-NEXT:             0x000000000000001f     12      3      0   0             0       0  is_stmt end_sequence
 
 ; generated from:
 ; clang -Oz -g -S -emit-llvm test.c -o test.ll
diff --git a/llvm/test/MC/ELF/debug-loc-label.s b/llvm/test/MC/ELF/debug-loc-label.s
index 6b5d04777bef4..4200b1192107b 100644
--- a/llvm/test/MC/ELF/debug-loc-label.s
+++ b/llvm/test/MC/ELF/debug-loc-label.s
@@ -17,43 +17,47 @@
 # CHECK-LINE-TABLE-NEXT: 0x0000002a: 00 DW_LNE_set_address (0x0000000000000000)
 # CHECK-LINE-TABLE-NEXT: 0x00000035: 01 DW_LNS_copy
 # CHECK-LINE-TABLE-NEXT:             0x0000000000000000      1      1      1   0             0       0  is_stmt
-# CHECK-LINE-TABLE-NEXT: 0x00000036: 00 DW_LNE_end_sequence
-# CHECK-LINE-TABLE-NEXT:             0x0000000000000000      1      1      1   0             0       0  is_stmt end_sequence
-# CHECK-LINE-TABLE-NEXT: 0x00000039: 05 DW_LNS_set_column (2)
-# CHECK-LINE-TABLE-NEXT: 0x0000003b: 00 DW_LNE_set_address (0x0000000000000008)
-# CHECK-LINE-TABLE-NEXT: 0x00000046: 01 DW_LNS_copy
+# CHECK-LINE-TABLE-NEXT: 0x00000036: 02 DW_LNS_advance_pc (addr += 8, op-index += 0)
+# CHECK-LINE-TABLE-NEXT: 0x00000038: 00 DW_LNE_end_sequence
+# CHECK-LINE-TABLE-NEXT:             0x0000000000000008      1      1      1   0             0       0  is_stmt end_sequence
+# CHECK-LINE-TABLE-NEXT: 0x0000003b: 05 DW_LNS_set_column (2)
+# CHECK-LINE-TABLE-NEXT: 0x0000003d: 00 DW_LNE_set_address (0x0000000000000008)
+# CHECK-LINE-TABLE-NEXT: 0x00000048: 01 DW_LNS_copy
 # CHECK-LINE-TABLE-NEXT:             0x0000000000000008      1      2      1   0             0       0  is_stmt
-# CHECK-LINE-TABLE-NEXT: 0x00000047: 00 DW_LNE_end_sequence
-# CHECK-LINE-TABLE-NEXT:             0x0000000000000008      1      2      1   0             0       0  is_stmt end_sequence
-# CHECK-LINE-TABLE-NEXT: 0x0000004a: 05 DW_LNS_set_column (3)
-# CHECK-LINE-TABLE-NEXT: 0x0000004c: 00 DW_LNE_set_address (0x0000000000000010)
-# CHECK-LINE-TABLE-NEXT: 0x00000057: 01 DW_LNS_copy
+# CHECK-LINE-TABLE-NEXT: 0x00000049: 02 DW_LNS_advance_pc (addr += 8, op-index += 0)
+# CHECK-LINE-TABLE-NEXT: 0x0000004b: 00 DW_LNE_end_sequence
+# CHECK-LINE-TABLE-NEXT:             0x0000000000000010      1      2      1   0             0       0  is_stmt end_sequence
+# CHECK-LINE-TABLE-NEXT: 0x0000004e: 05 DW_LNS_set_column (3)
+# CHECK-LINE-TABLE-NEXT: 0x00000050: 00 DW_LNE_set_address (0x0000000000000010)
+# CHECK-LINE-TABLE-NEXT: 0x0000005b: 01 DW_LNS_copy
 # CHECK-LINE-TABLE-NEXT:             0x0000000000000010      1      3      1   0             0       0  is_stmt
-# CHECK-LINE-TABLE-NEXT: 0x00000058: 00 DW_LNE_end_sequence
-# CHECK-LINE-TABLE-NEXT:             0x0000000000000010      1      3      1   0             0       0  is_stmt end_sequence
-# CHECK-LINE-TABLE-NEXT: 0x0000005b: 05 DW_LNS_set_column (4)
-# CHECK-LINE-TABLE-NEXT: 0x0000005d: 00 DW_LNE_set_address (0x0000000000000018)
-# CHECK-LINE-TABLE-NEXT: 0x00000068: 01 DW_LNS_copy
+# CHECK-LINE-TABLE-NEXT: 0x0000005c: 02 DW_LNS_advance_pc (addr += 8, op-index += 0)
+# CHECK-LINE-TABLE-NEXT: 0x0000005e: 00 DW_LNE_end_sequence
+# CHECK-LINE-TABLE-NEXT:             0x0000000000000018      1      3      1   0             0       0  is_stmt end_sequence
+# CHECK-LINE-TABLE-NEXT: 0x00000061: 05 DW_LNS_set_column (4)
+# CHECK-LINE-TABLE-NEXT: 0x00000063: 00 DW_LNE_set_address (0x0000000000000018)
+# CHECK-LINE-TABLE-NEXT: 0x0000006e: 01 DW_LNS_copy
 # CHECK-LINE-TABLE-NEXT:             0x0000000000000018      1      4      1   0             0       0  is_stmt
-# CHECK-LINE-TABLE-NEXT: 0x00000069: 05 DW_LNS_set_column (5)
-# CHECK-LINE-TABLE-NEXT: 0x0000006b: 01 DW_LNS_copy
+# CHECK-LINE-TABLE-NEXT: 0x0000006f: 05 DW_LNS_set_column (5)
+# CHECK-LINE-TABLE-NEXT: 0x00000071: 01 DW_LNS_copy
 # CHECK-LINE-TABLE-NEXT:             0x0000000000000018      1      5      1   0             0       0  is_stmt
-# CHECK-LINE-TABLE-NEXT: 0x0000006c: 00 DW_LNE_end_sequence
-# CHECK-LINE-TABLE-NEXT:             0x0000000000000018      1      5      1   0             0       0  is_stmt end_sequence
+# CHECK-LINE-TABLE-NEXT: 0x00000072: 02 DW_LNS_advance_pc (addr += 8, op-index += 0)
+# CHECK-LINE-TABLE-NEXT: 0x00000074: 00 DW_LNE_end_sequence
+# CHECK-LINE-TABLE-NEXT:             0x0000000000000020      1      5      1   0             0       0  is_stmt end_sequence
 
 # CHECK-SYM:      Symbol table '.symtab' contains 9 entries:
 # CHECK-SYM-NEXT:    Num:    Value          Size Type    Bind   Vis       Ndx Name
 # CHECK-SYM-NEXT:      0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT   UND
 # CHECK-SYM-NEXT:      1: 0000000000000000     0 FILE    LOCAL  DEFAULT   ABS test.c
 # CHECK-SYM-NEXT:      2: 0000000000000000     0 SECTION LOCAL  DEFAULT     2 .text
-# CHECK-SYM-NEXT:      3: 0000000000000039     0 NOTYPE  LOCAL  DEFAULT     3 my_label_02
-# CHECK-SYM-NEXT:      4: 000000000000004a     0 NOTYPE  LOCAL  DEFAULT     3 my_label_03
-# CHECK-SYM-NEXT:      5: 000000000000005b     0 NOTYPE  LOCAL  DEFAULT     3 my_label_04
-# CHECK-SYM-NEXT:      6: 000000000000004a     0 NOTYPE  LOCAL  DEFAULT     3 my_label_03.1
-# CHECK-SYM-NEXT:      7: 000000000000006f     0 NOTYPE  LOCAL  DEFAULT     3 my_label_05
+# CHECK-SYM-NEXT:      3: 000000000000003b     0 NOTYPE  LOCAL  DEFAULT     3 my_label_02
+# CHECK-SYM-NEXT:      4: 000000000000004e     0 NOTYPE  LOCAL  DEFAULT     3 my_label_03
+# CHECK-SYM-NEXT:      5: 0000000000000061     0 NOTYPE  LOCAL  DEFAULT     3 my_label_04
+# CHECK-SYM-NEXT:      6: 000000000000004e     0 NOTYPE  LOCAL  DEFAULT     3 my_label_03.1
+# CHECK-SYM-NEXT:      7: 0000000000000077     0 NOTYPE  LOCAL  DEFAULT     3 my_label_05
 # CHECK-SYM-NEXT:      8: 0000000000000000     0 FUNC    GLOBAL DEFAULT     2 foo
 
-# CHECK-OFFSETS: 0000 39000000 4a000000 5b000000
+# CHECK-OFFSETS: 0000 3b000000 4e000000 61000000
 
 	.text
 	.file	"test.c"

@DataCorrupted
Copy link
Member Author

cc @nocchijiang , I can't tag you as a reviewer somehow

@DataCorrupted
Copy link
Member Author

@rastogishubham / @adrian-prantl You mentioned a bug in #110192, which wasn't really fixed there. This PR fixed the issue, but I wonder if it will work fine with your fork. Let me know if you have any comments.

DataCorrupted referenced this pull request Sep 8, 2025
…ries (#133079)

When hitting a sanitizer breakpoint, LLDB currently displays the frame
in the sanitizer dylib (which we usually don't have debug-info for),
which isn't very helpful to the user. A more helpful frame to display
would be the first frame not in the sanitizer library (we have a
[similar heuristic when we trap inside
libc++](#108825)). This patch
does just that, by implementing the `GetSuggestedStackFrameIndex` API

Depends on #133078
@DataCorrupted
Copy link
Member Author

@dwblaikie Can I get a quick review pls?

Copy link
Collaborator

@dwblaikie dwblaikie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shrug I'm not especially familiar with this code, but the resulting changes seem OK & doesn't seem too invasive...

@DataCorrupted
Copy link
Member Author

@dwblaikie Confirming the tests are correct is a huge help to us. Thanks!

@DataCorrupted DataCorrupted merged commit 84f431c into llvm:main Sep 12, 2025
9 checks passed
@llvm-ci
Copy link
Collaborator

llvm-ci commented Sep 12, 2025

LLVM Buildbot has detected a new failure on builder ml-opt-rel-x86-64 running on ml-opt-rel-x86-64-b1 while building llvm at step 6 "test-build-unified-tree-check-all".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/185/builds/25273

Here is the relevant piece of the build log for the reference
Step 6 (test-build-unified-tree-check-all) failure: test (failure)
******************** TEST 'LLVM :: DebugInfo/ARM/stmt_seq_macho.test' FAILED ********************
Exit Code: 127

Command Output (stdout):
--
# RUN: at line 1
split-file /b/ml-opt-rel-x86-64-b1/llvm-project/llvm/test/DebugInfo/ARM/stmt_seq_macho.test /b/ml-opt-rel-x86-64-b1/build/test/DebugInfo/ARM/Output/stmt_seq_macho.test.tmp
# executed command: split-file /b/ml-opt-rel-x86-64-b1/llvm-project/llvm/test/DebugInfo/ARM/stmt_seq_macho.test /b/ml-opt-rel-x86-64-b1/build/test/DebugInfo/ARM/Output/stmt_seq_macho.test.tmp
# RUN: at line 3
clang++ --target=arm64-apple-macos11    /b/ml-opt-rel-x86-64-b1/build/test/DebugInfo/ARM/Output/stmt_seq_macho.test.tmp/stmt_seq_macho.cpp -o /b/ml-opt-rel-x86-64-b1/build/test/DebugInfo/ARM/Output/stmt_seq_macho.test.tmp/stmt_seq_macho.o    -g -Oz -gdwarf-4 -c -mno-outline    -mllvm -emit-func-debug-line-table-offsets    -fdebug-compilation-dir=/private/tmp/stmt_seq    -fno-unwind-tables -fno-exceptions
# executed command: clang++ --target=arm64-apple-macos11 /b/ml-opt-rel-x86-64-b1/build/test/DebugInfo/ARM/Output/stmt_seq_macho.test.tmp/stmt_seq_macho.cpp -o /b/ml-opt-rel-x86-64-b1/build/test/DebugInfo/ARM/Output/stmt_seq_macho.test.tmp/stmt_seq_macho.o -g -Oz -gdwarf-4 -c -mno-outline -mllvm -emit-func-debug-line-table-offsets -fdebug-compilation-dir=/private/tmp/stmt_seq -fno-unwind-tables -fno-exceptions
# .---command stderr------------
# | 'clang++': command not found
# `-----------------------------
# error: command failed with exit status: 127

--

********************


@llvm-ci
Copy link
Collaborator

llvm-ci commented Sep 12, 2025

LLVM Buildbot has detected a new failure on builder ml-opt-dev-x86-64 running on ml-opt-dev-x86-64-b2 while building llvm at step 6 "test-build-unified-tree-check-all".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/137/builds/25430

Here is the relevant piece of the build log for the reference
Step 6 (test-build-unified-tree-check-all) failure: test (failure)
******************** TEST 'LLVM :: DebugInfo/ARM/stmt_seq_macho.test' FAILED ********************
Exit Code: 127

Command Output (stdout):
--
# RUN: at line 1
split-file /b/ml-opt-dev-x86-64-b1/llvm-project/llvm/test/DebugInfo/ARM/stmt_seq_macho.test /b/ml-opt-dev-x86-64-b1/build/test/DebugInfo/ARM/Output/stmt_seq_macho.test.tmp
# executed command: split-file /b/ml-opt-dev-x86-64-b1/llvm-project/llvm/test/DebugInfo/ARM/stmt_seq_macho.test /b/ml-opt-dev-x86-64-b1/build/test/DebugInfo/ARM/Output/stmt_seq_macho.test.tmp
# RUN: at line 3
clang++ --target=arm64-apple-macos11    /b/ml-opt-dev-x86-64-b1/build/test/DebugInfo/ARM/Output/stmt_seq_macho.test.tmp/stmt_seq_macho.cpp -o /b/ml-opt-dev-x86-64-b1/build/test/DebugInfo/ARM/Output/stmt_seq_macho.test.tmp/stmt_seq_macho.o    -g -Oz -gdwarf-4 -c -mno-outline    -mllvm -emit-func-debug-line-table-offsets    -fdebug-compilation-dir=/private/tmp/stmt_seq    -fno-unwind-tables -fno-exceptions
# executed command: clang++ --target=arm64-apple-macos11 /b/ml-opt-dev-x86-64-b1/build/test/DebugInfo/ARM/Output/stmt_seq_macho.test.tmp/stmt_seq_macho.cpp -o /b/ml-opt-dev-x86-64-b1/build/test/DebugInfo/ARM/Output/stmt_seq_macho.test.tmp/stmt_seq_macho.o -g -Oz -gdwarf-4 -c -mno-outline -mllvm -emit-func-debug-line-table-offsets -fdebug-compilation-dir=/private/tmp/stmt_seq -fno-unwind-tables -fno-exceptions
# .---command stderr------------
# | 'clang++': command not found
# `-----------------------------
# error: command failed with exit status: 127

--

********************


@llvm-ci
Copy link
Collaborator

llvm-ci commented Sep 12, 2025

LLVM Buildbot has detected a new failure on builder ml-opt-devrel-x86-64 running on ml-opt-devrel-x86-64-b1 while building llvm at step 6 "test-build-unified-tree-check-all".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/175/builds/25273

Here is the relevant piece of the build log for the reference
Step 6 (test-build-unified-tree-check-all) failure: test (failure)
******************** TEST 'LLVM :: DebugInfo/ARM/stmt_seq_macho.test' FAILED ********************
Exit Code: 127

Command Output (stdout):
--
# RUN: at line 1
split-file /b/ml-opt-devrel-x86-64-b1/llvm-project/llvm/test/DebugInfo/ARM/stmt_seq_macho.test /b/ml-opt-devrel-x86-64-b1/build/test/DebugInfo/ARM/Output/stmt_seq_macho.test.tmp
# executed command: split-file /b/ml-opt-devrel-x86-64-b1/llvm-project/llvm/test/DebugInfo/ARM/stmt_seq_macho.test /b/ml-opt-devrel-x86-64-b1/build/test/DebugInfo/ARM/Output/stmt_seq_macho.test.tmp
# RUN: at line 3
clang++ --target=arm64-apple-macos11    /b/ml-opt-devrel-x86-64-b1/build/test/DebugInfo/ARM/Output/stmt_seq_macho.test.tmp/stmt_seq_macho.cpp -o /b/ml-opt-devrel-x86-64-b1/build/test/DebugInfo/ARM/Output/stmt_seq_macho.test.tmp/stmt_seq_macho.o    -g -Oz -gdwarf-4 -c -mno-outline    -mllvm -emit-func-debug-line-table-offsets    -fdebug-compilation-dir=/private/tmp/stmt_seq    -fno-unwind-tables -fno-exceptions
# executed command: clang++ --target=arm64-apple-macos11 /b/ml-opt-devrel-x86-64-b1/build/test/DebugInfo/ARM/Output/stmt_seq_macho.test.tmp/stmt_seq_macho.cpp -o /b/ml-opt-devrel-x86-64-b1/build/test/DebugInfo/ARM/Output/stmt_seq_macho.test.tmp/stmt_seq_macho.o -g -Oz -gdwarf-4 -c -mno-outline -mllvm -emit-func-debug-line-table-offsets -fdebug-compilation-dir=/private/tmp/stmt_seq -fno-unwind-tables -fno-exceptions
# .---command stderr------------
# | 'clang++': command not found
# `-----------------------------
# error: command failed with exit status: 127

--

********************


@llvm-ci
Copy link
Collaborator

llvm-ci commented Sep 12, 2025

LLVM Buildbot has detected a new failure on builder lld-x86_64-ubuntu-fast running on as-builder-4 while building llvm at step 6 "test-build-unified-tree-check-all".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/33/builds/22944

Here is the relevant piece of the build log for the reference
Step 6 (test-build-unified-tree-check-all) failure: test (failure)
******************** TEST 'LLVM :: DebugInfo/ARM/stmt_seq_macho.test' FAILED ********************
Exit Code: 127

Command Output (stdout):
--
# RUN: at line 1
split-file /home/buildbot/worker/as-builder-4/ramdisk/lld-x86_64/llvm-project/llvm/test/DebugInfo/ARM/stmt_seq_macho.test /home/buildbot/worker/as-builder-4/ramdisk/lld-x86_64/build/test/DebugInfo/ARM/Output/stmt_seq_macho.test.tmp
# executed command: split-file /home/buildbot/worker/as-builder-4/ramdisk/lld-x86_64/llvm-project/llvm/test/DebugInfo/ARM/stmt_seq_macho.test /home/buildbot/worker/as-builder-4/ramdisk/lld-x86_64/build/test/DebugInfo/ARM/Output/stmt_seq_macho.test.tmp
# RUN: at line 3
clang++ --target=arm64-apple-macos11    /home/buildbot/worker/as-builder-4/ramdisk/lld-x86_64/build/test/DebugInfo/ARM/Output/stmt_seq_macho.test.tmp/stmt_seq_macho.cpp -o /home/buildbot/worker/as-builder-4/ramdisk/lld-x86_64/build/test/DebugInfo/ARM/Output/stmt_seq_macho.test.tmp/stmt_seq_macho.o    -g -Oz -gdwarf-4 -c -mno-outline    -mllvm -emit-func-debug-line-table-offsets    -fdebug-compilation-dir=/private/tmp/stmt_seq    -fno-unwind-tables -fno-exceptions
# executed command: clang++ --target=arm64-apple-macos11 /home/buildbot/worker/as-builder-4/ramdisk/lld-x86_64/build/test/DebugInfo/ARM/Output/stmt_seq_macho.test.tmp/stmt_seq_macho.cpp -o /home/buildbot/worker/as-builder-4/ramdisk/lld-x86_64/build/test/DebugInfo/ARM/Output/stmt_seq_macho.test.tmp/stmt_seq_macho.o -g -Oz -gdwarf-4 -c -mno-outline -mllvm -emit-func-debug-line-table-offsets -fdebug-compilation-dir=/private/tmp/stmt_seq -fno-unwind-tables -fno-exceptions
# .---command stderr------------
# | 'clang++': command not found
# `-----------------------------
# error: command failed with exit status: 127

--

********************


dwblaikie added a commit that referenced this pull request Sep 12, 2025
dwblaikie added a commit that referenced this pull request Sep 12, 2025
Reverts #157529

Sorry, I missed that the missed that the LLVM test was using clang -
layering dictates thats not OK. Please readjust the test case to work
like the existing test coverage (or perhaps the existing test coverage
is sufficient?) and post a new PR.
llvm-sync bot pushed a commit to arm/arm-toolchain that referenced this pull request Sep 16, 2025
Reverts llvm/llvm-project#157529

Sorry, I missed that the missed that the LLVM test was using clang -
layering dictates thats not OK. Please readjust the test case to work
like the existing test coverage (or perhaps the existing test coverage
is sufficient?) and post a new PR.
dwblaikie pushed a commit that referenced this pull request Sep 16, 2025
This reverts commit aabf18d.
#157529 included a test that used clang, which doesn't exists in some
CI. #158343 reverts it.

This PR reapplies the original patch with the incorrect test removed.

### Context

#99710 introduced `.loc_label` so we can terminate a line sequence.
However, it did not advance PC properly. This is problematic for
1-instruction functions as it will have zero-length sequence. The test
checked in that PR shows the problem:

```
# CHECK-LINE-TABLE:                  Address            Line   Column File   ISA Discriminator OpIndex Flags
# CHECK-LINE-TABLE-NEXT:             ------------------ ------ ------ ------ --- ------------- ------- -------------
# CHECK-LINE-TABLE-NEXT: 0x00000028: 05 DW_LNS_set_column (1)
# CHECK-LINE-TABLE-NEXT: 0x0000002a: 00 DW_LNE_set_address (0x0000000000000000)
# CHECK-LINE-TABLE-NEXT: 0x00000035: 01 DW_LNS_copy
# CHECK-LINE-TABLE-NEXT:             0x0000000000000000      1      1      1   0             0       0  is_stmt
# CHECK-LINE-TABLE-NEXT: 0x00000036: 00 DW_LNE_end_sequence
# CHECK-LINE-TABLE-NEXT:             0x0000000000000000      1      1      1   0             0       0  is_stmt end_sequence
```

Both rows having PC 0x0 is incorrect, and parsers won't be able to parse
them. See more explanation why this is wrong in #154851.

### Design

This PR attempts to fix this by advancing the PC to the next available
Label, and advance to the end of the section if no Label is available.

### Implementation

- `emitDwarfLineEndEntry` will advance PC to the `CurrLabel`
- If `CurrLabel` is null, its probably a fake LineEntry we introduced in
#110192. In that case look for the next Label
- If still not label can be found, use `null` and
`emitDwarfLineEndEntry` is smart enough to advance PC to the end of the
section
- Rename `LastLabel` to `PrevLabel`, "last" can mean "previous" or
"final", this is ambigous.
- Updated the tests to emit a correct label.

### Note

This fix should render #154986 and #154851 obsolete, they were temporary
fixes and don't resolve the root cause.
kimsh02 pushed a commit to kimsh02/llvm-project that referenced this pull request Sep 19, 2025
…#158379)

This reverts commit aabf18d.
llvm#157529 included a test that used clang, which doesn't exists in some
CI. llvm#158343 reverts it.

This PR reapplies the original patch with the incorrect test removed.

### Context

llvm#99710 introduced `.loc_label` so we can terminate a line sequence.
However, it did not advance PC properly. This is problematic for
1-instruction functions as it will have zero-length sequence. The test
checked in that PR shows the problem:

```
# CHECK-LINE-TABLE:                  Address            Line   Column File   ISA Discriminator OpIndex Flags
# CHECK-LINE-TABLE-NEXT:             ------------------ ------ ------ ------ --- ------------- ------- -------------
# CHECK-LINE-TABLE-NEXT: 0x00000028: 05 DW_LNS_set_column (1)
# CHECK-LINE-TABLE-NEXT: 0x0000002a: 00 DW_LNE_set_address (0x0000000000000000)
# CHECK-LINE-TABLE-NEXT: 0x00000035: 01 DW_LNS_copy
# CHECK-LINE-TABLE-NEXT:             0x0000000000000000      1      1      1   0             0       0  is_stmt
# CHECK-LINE-TABLE-NEXT: 0x00000036: 00 DW_LNE_end_sequence
# CHECK-LINE-TABLE-NEXT:             0x0000000000000000      1      1      1   0             0       0  is_stmt end_sequence
```

Both rows having PC 0x0 is incorrect, and parsers won't be able to parse
them. See more explanation why this is wrong in llvm#154851.

### Design

This PR attempts to fix this by advancing the PC to the next available
Label, and advance to the end of the section if no Label is available.

### Implementation

- `emitDwarfLineEndEntry` will advance PC to the `CurrLabel`
- If `CurrLabel` is null, its probably a fake LineEntry we introduced in
llvm#110192. In that case look for the next Label
- If still not label can be found, use `null` and
`emitDwarfLineEndEntry` is smart enough to advance PC to the end of the
section
- Rename `LastLabel` to `PrevLabel`, "last" can mean "previous" or
"final", this is ambigous.
- Updated the tests to emit a correct label.

### Note

This fix should render llvm#154986 and llvm#154851 obsolete, they were temporary
fixes and don't resolve the root cause.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
debuginfo llvm:mc Machine (object) code
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants