blog/content/posts/gdb-and-systemtap-probes-part-1.md

98 lines
3.4 KiB
Markdown

---
date: 2012-03-29T00:00:00-05:00
title: "GDB and SystemTap probes -- part 1"
tags: [gdb, fedora-planet, systemtap, howto, en_us, english, free-software]
---
After a long time, here we are again :-).
With this post I will start to talk about the integration between GDB
and SystemTap. This is something that [Tom
Tromey](http://tromey.com/blog/) and I did during the last year. The
patch is being reviewed as I write this post, and I expect to see it
checked-in in the next few days/weeks. But let's get our hands dirty...
SystemTap Userspace Probes
--------------------------
You probably use (or have at least heard of) SystemTap, and maybe you
think the tool is only useful for kernel inspections. If that's your
case, I have a good news: you're wrong! You can actually use SystemTap
to inspect userspace applications too, by using what we call **SDT
probes**, or *S*tatic *D*efined *T*racing probes. This is a very cheap
and easy way to include probes in your application, and you can even
specify arguments to those probes.
In order to use the probes (see an example below), you must include the
`<sys/sdt.h>` header file in your source code. If you are using Fedora
systems, you can obtain this header file by installing the package
`systemtap-sdt-devel`, version equal or greater than `1.4`.
Here's a simple example of an application with a one-argument probe:
```c
#include <sys/sdt.h>
int
main (int argc, char *argv[])
{
int a = 10;
STAP_PROBE1 (test_program, my_probe, a);
return 0;
}
```
As you can see, this is a very simple program with one probe, which
contains one argument. You can now compile the program:
```console
$ gcc test_program.c -o test_program
```
Now you must be thinking: "*Wait, wait... Didn't you just forget to link
this program against some SystemTap-specific library or something?*" And
my answer is **no**. One of the spetacular things about this
`<sys/sdt.h>` header is that it does not have any dependencies at all!
As Tom said in [his blog post](http://tromey.com/blog/?p=687), this is
"*a virtuoso display of ELF and GCC asm wizardy*".
If you want to make sure your probe was inserted in the binary, you can
use `readelf` command:
```console
$ readelf -x .note.stapsdt ./test_program
Hex dump of section '.note.stapsdt':
0x00000000 08000000 3a000000 03000000 73746170 ....:.......stap
0x00000010 73647400 86044000 00000000 88054000 sdt...@.......@.
0x00000020 00000000 00000000 00000000 74657374 ............test
0x00000030 5f70726f 6772616d 006d795f 70726f62 _program.my_prob
0x00000040 65002d34 402d3428 25726270 29000000 e.-4@-4(%rbp)...
```
*(I will think about writing an explanation on how the probes are laid
out on the binary, but for now you just have to care if you actually
see an output from this* `readelf` *command.)*
You can also use SystemTap to perform this verification:
```console
$ stap -L 'process("./test_program").mark("*")'
process("./test_program").mark("my_probe") $arg1:long
```
So far, so good. If you see an output like the one above, it means your
probe is correctly inserted. You could obviously use SystemTap to
inspect this probe, but I won't do this right now because this is not
the purpose of this post.
For now, we have learned how to:
1. Include an `SDT probe` in our source code, and compile it;
2. Verify if the probe was correctly inserted.
In the next post, I will talk about the GDB support that allows you to
inspect, print arguments, and gather other information about
`SDT probes`. I hope you like it!