I tried "breakpoint [line number]", "breakpoint filename.s:line_number" but they don't work. Currently I have to step through all lines, and it's a hassle
As an alternative you can:
show memory with assembly instructions with
di with explicit arguments
if you need reach out further
di -c 1000 ;
if you need to disassemble a specific address
di -s <address>
set a memory break point with
br s -a
Another alternative / (not valid for MacOS Monterey 12.x and newer)
is slightly more destructive but actually more effortless , which may or may not be useful in your case. You can make an invalid syscall in your assembly code. Your program will happily continue execution but lldb
will break on the next instruction after the syscall with SIGSYS
/EXC_SYSCALL
. You haven't specified if you're targetting x86-64 or arm so the setup will differ slightly.
For x86-64 you'd have
syscall
Assuming your rax
register does not happen to be a valid syscall i.e in 0x2000xxx
range the destructive part will include:
Zeroing upper 32bits of rax
register
r11
will become rflags
rcx
will become rip
(it's used by the XNU kernel for returning to the user space from the syscall
), however if you single step rcx
will become rsp
as mentioned by me here
For 32 bit and 64bit arm you can make a system call with:
svc 0x80
Btw any 1 byte^ number will work, but by convention it's 0x80
.
32bit uses r12
for syscall number. 64bit uses x16
. More info here & here. So basically valid ranges are 0x0
- 0x0xxx
. Even invalid syscalls seem to affect x0
& x1
(for 64bit, as I don't have a 32bit device to test). So as long as you take into account x0
& x1
being affected after the syscall and happen to have x16
that is an invalid syscall you're good to go.
UPDATE To @PeterCordes excellent remark yet another alternative for x86 is:
int3
i.e. debugger trap
32bit arm equivalent is
trap
64 bit arm equivalent is
brk #0xf000
The difference vs syscall
approach is the program execution after int3
/ trap
/ brk #0xf000
will continue if and only if debugger is attached and lldb continue
command follows, the added value is it won't affect the registers at all. In the syscall approach the program will also continue execution without debugger attached with the aforementioned registers affected.