This is what the gdb script looks like:
set height 0
catch syscall close
catch syscall read
catch syscall lseek
disable 1 2
commands 2
disable 1 2
continue
end
commands 3
if $rdi == 31
enable 1 2
continue
else
continue
end
end
The lseek catchpoint (3) enables both read and close catchpoints; if the read catchpoint (2) is hit first it disables both and continues. This way we look for lseek followed by close without intervening reads.It generates a few false positives but otherwise fairly quickly stops on the right syscall, at which point I could backtrace and prod the live program.
I've never seen any resource on "how to gdb a really gnarly bug"; this is a great example.
Can you recommend any good resources to learn more about this? Should I just study the LLDB/GDB references? Or maybe if you think there are not much good resources on this, maybe it would be a good idea if you could write a blog post about this?
LLDB doesn't appear to have a way to set a breakpoint at syscalls, unfortunately. If it's dynamically linked, however, it will probably go through your platform's libc so you can probably achieve the same effect by breaking on all of the syscall wrapper functions.
It's not a toy: it can debug Google Chrome, Libre Office, and QEMU. However, RR is Linux-only.
Thanks alehander42!