[Lldb-commits] [lldb] [lldb] Step over non-lldb breakpoints (PR #174348)

David Spickett via lldb-commits lldb-commits at lists.llvm.org
Mon Feb 9 03:54:05 PST 2026


DavidSpickett wrote:

```
int main() {
  __builtin_debugtrap();
  return 0;
}
```
Compiled with clang:
```
0000000000000714 <main>:
 714:   d10043ff        sub     sp, sp, #0x10
 718:   2a1f03e0        mov     w0, wzr
 71c:   b9000fff        str     wzr, [sp, #12]
 720:   d43e0000        brk     #0xf000
 724:   910043ff        add     sp, sp, #0x10
 728:   d65f03c0        ret
```
I can continue from the debugtrap:
```
$ ./bin/lldb /tmp/test.o
(lldb) target create "/tmp/test.o"
Current executable set to '/tmp/test.o' (aarch64).
(lldb) run
Process 36194 launched: '/tmp/test.o' (aarch64)
Process 36194 stopped
* thread #1, name = 'test.o', stop reason = signal SIGTRAP
    frame #0: 0x0000aaaaaaaa0724 test.o`main at test.c:3:3
   1   	int main() {
   2   	  __builtin_debugtrap();
-> 3   	  return 0;
   4   	}
(lldb) c
Process 36194 resuming
Process 36194 exited with status = 0 (0x00000000)
```
This is an improvement. I also tried the testcase and that works.

What confused me was I did this:
```
$ ./bin/lldb /tmp/test.o
(lldb) target create "/tmp/test.o"
Current executable set to '/tmp/test.o' (aarch64).
(lldb) b main
Breakpoint 1: where = test.o`main + 12 at test.c:2:3, address = 0x0000000000000720
(lldb) run
Process 36228 launched: '/tmp/test.o' (aarch64)
Process 36228 stopped
* thread #1, name = 'test.o', stop reason = breakpoint 1.1
    frame #0: 0x0000aaaaaaaa0720 test.o`main at test.c:2:3
   1   	int main() {
-> 2   	  __builtin_debugtrap();
   3   	  return 0;
   4   	}
(lldb) dis
test.o`main:
    0xaaaaaaaa0714 <+0>:  sub    sp, sp, #0x10
    0xaaaaaaaa0718 <+4>:  mov    w0, wzr
    0xaaaaaaaa071c <+8>:  str    wzr, [sp, #0xc]
->  0xaaaaaaaa0720 <+12>: brk    #0xf000
    0xaaaaaaaa0724 <+16>: add    sp, sp, #0x10
    0xaaaaaaaa0728 <+20>: ret    
(lldb) c
Process 36228 resuming
<ctrl-c>
Process 36228 stopped
* thread #1, name = 'test.o', stop reason = breakpoint 1.1
    frame #0: 0x0000aaaaaaaa0720 test.o`main at test.c:2:3
   1   	int main() {
-> 2   	  __builtin_debugtrap();
   3   	  return 0;
   4   	}
(lldb) dis
test.o`main:
    0xaaaaaaaa0714 <+0>:  sub    sp, sp, #0x10
    0xaaaaaaaa0718 <+4>:  mov    w0, wzr
    0xaaaaaaaa071c <+8>:  str    wzr, [sp, #0xc]
->  0xaaaaaaaa0720 <+12>: brk    #0xf000
    0xaaaaaaaa0724 <+16>: add    sp, sp, #0x10
    0xaaaaaaaa0728 <+20>: ret 
```
If you happen to breakpoint on a breakpoint already in the inferior, then you can't get off of it.
```
(lldb) breakpoint list -v
Current breakpoints:
1: name = 'main'
    1.1: 
      module = /tmp/test.o
      compile unit = test.c
      function = main
      location = /tmp/test.c:2:3
      address = 0x0000aaaaaaaa0720
      resolved = true
      hardware = false
      hit count = 62003
```
We're placing a software break over the inferior's software break.

Which is not the problem in itself, because it happens with a hardware break too:
```
$ ./bin/lldb /tmp/test.o
(lldb) target create "/tmp/test.o"
Current executable set to '/tmp/test.o' (aarch64).
(lldb) settings set target.require-hardware-breakpoint true
(lldb) b main
Breakpoint 1: where = test.o`main + 12 at test.c:2:3, address = 0x0000000000000720
(lldb) run
Process 36363 launched: '/tmp/test.o' (aarch64)
Process 36363 stopped
* thread #1, name = 'test.o', stop reason = breakpoint 1.1
    frame #0: 0x0000aaaaaaaa0720 test.o`main at test.c:2:3
   1   	int main() {
-> 2   	  __builtin_debugtrap();
   3   	  return 0;
   4   	}
(lldb) breakpoint list -v
Current breakpoints:
1: name = 'main'
    1.1: 
      module = /tmp/test.o
      compile unit = test.c
      function = main
      location = /tmp/test.c:2:3
      address = 0x0000aaaaaaaa0720
      resolved = true
      hardware = true
      hit count = 1   


(lldb) dis
test.o`main:
    0xaaaaaaaa0714 <+0>:  sub    sp, sp, #0x10
    0xaaaaaaaa0718 <+4>:  mov    w0, wzr
    0xaaaaaaaa071c <+8>:  str    wzr, [sp, #0xc]
->  0xaaaaaaaa0720 <+12>: brk    #0xf000
    0xaaaaaaaa0724 <+16>: add    sp, sp, #0x10
    0xaaaaaaaa0728 <+20>: ret    
(lldb) c
Process 36363 resuming
<ctrl-c>
Process 36363 stopped
* thread #1, name = 'test.o', stop reason = breakpoint 1.1
    frame #0: 0x0000aaaaaaaa0720 test.o`main at test.c:2:3
   1   	int main() {
-> 2   	  __builtin_debugtrap();
   3   	  return 0;
   4   	}
(lldb) dis
test.o`main:
    0xaaaaaaaa0714 <+0>:  sub    sp, sp, #0x10
    0xaaaaaaaa0718 <+4>:  mov    w0, wzr
    0xaaaaaaaa071c <+8>:  str    wzr, [sp, #0xc]
->  0xaaaaaaaa0720 <+12>: brk    #0xf000
    0xaaaaaaaa0724 <+16>: add    sp, sp, #0x10
    0xaaaaaaaa0728 <+20>: ret
```

I'd be ok with accepting this PR as an improvement over the current situation.

Unless this is a situation you think your code:
* Should already handle
* Could handle with a small change

If it's gonna be a large and/or complex change, it's best in its own PR anyway. And I'll note on the issue that it is partially fixed.

https://github.com/llvm/llvm-project/pull/174348


More information about the lldb-commits mailing list