Here’s a homework problem for you: design a static probe point API that:
- Consists of a single header file,
- Works for C, C++, and assembly,
- Allows probes to have arguments,
- Does not require any overhead for computing the arguments if they are already live,
- Does not require debuginfo for debug tools to extract argument values,
- Has overhead no greater than a single nop when no debugger is attached, and
- Needs no dynamic relocations.
I wouldn’t have accepted this task, but Roland McGrath, in a virtuoso display of ELF and GCC asm wizardy, wrote
<sys/sdt.h> for SystemTap. Version 3 has all the properties listed above. I’m pretty amazed by it.
This past year, Sergio Durigan Junior and I added support for this to gdb. It is already in Fedora, of course, and it will be showing up in upstream gdb soon.
The way I think about these probes is that they let you name a place in your code in a way that is relatively independent of source changes. gdb can already address functions nicely (
"break function") or lines (
"break file.c:73") — but sometimes I’d like a stable breakpoint location that is not on a function boundary; but using line numbers in a
.gdbinit or other script is hard, because line numbers change when I edit.
We’ve also added probes to a few libraries in the distro, for gdb to use internally. For example, we added probes to the unwind functions in libgcc, so that gdb can properly “next” over code that throws exceptions. And, we did something similar for
longjmp in glibc. You can dump the probes from a library with
readelf -n, or with “info probes” in gdb.
The probes were designed to be source-compatible with DTrace static probes. So, if you are already using those, you can just install the appropriate header from SystemTap. Otherwise, adding the probes is quite easy… see the instructions, but be warned that they focus a bit too much on DTrace compability; you probably don’t want the .d file and the semaphore, that just slows things down. Instead I recommend just including the header and using the macros directly.