Skip to content

prologue_end since LLVM20 misleads gdb into setting flawed breakpoints #139549

Closed
@jmorse

Description

@jmorse

While working on the reproducer from #135937, I discovered that gdb really doesn't like the new placement of prologue_end since #107849 and related patches. The code:

 1  int printf(const char *, ...);
 2  int a, c;
 3  unsigned b = 5;
 4  int d() {
 5    if (b)
 6      return b;
 7    c = 8;  // Dead code here
 8  }
 9  int main() {
10    d();
11    printf("%X\n", a);
12  }

Compiled with clang 3b4f9c5 -g -O2 produces this code at the beginning of main:

0000000000001160 <main>:
    1160:       83 3d c9 2e 00 00 00    cmpl   $0x0,0x2ec9(%rip)        # 4030 <b>
    1167:       75 0a                   jne    1173 <main+0x13>
    1169:       c7 05 c5 2e 00 00 08    movl   $0x8,0x2ec5(%rip)        # 4038 <c>
    1170:       00 00 00

Which has this linetable:

0x0000000000001160      5      7      0   0             0  is_stmt prologue_end
0x0000000000001169      7      5      0   0             0  is_stmt
0x0000000000001174     11     18      0   0             0  is_stmt

i.e., the first line is part of d that's been inlined, and the prologue immediately ends. LLDB is happy with this, the SCE debugger is happy with this, however gdb:

(gdb) start
Temporary breakpoint 1 at 0x1169: file /tmp/wat.c, line 10.
[runs to completion]

places the initial breakpoint for 'main' on the line entry /after/ prologue_end, which is past the first branch instruction. As a result, the path taken through main isn't completely covered by that breakpoint, and the program never stops. This is undesirable. The gdb version string I have locally is GNU gdb (Ubuntu 12.1-0ubuntu1~22.04.2) 12.1.

DWARF5 describes the prologue_end flag thusly:

A boolean indicating that the current address is one (of possibly many) where execution should be suspended for a breakpoint at the entry of a function

Which I feel naturally means that the address to suspend execution is that address where prologue_end is. i.e. 0x1160 in this example. gdb would appear to have an interpretation that I'm unfamiliar with.

Next steps are, I believe:

  • If someone has a different interpretation of prologue_end, or can explain why gdb behaves in this way, please do tell me!,
  • Otherwise I'll try to replicate with the latest version of gdb,
  • And if it replicates, I'll report to gdb to see what they think the correct behaviour should be.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions