Wednesday, 22 February 2012

simple application-level tracing with

Linux provides a plethora of useful trace tools. Two of the most command and the most useful being strace, for tracing system calls and ltrace that traces library calls (it can also trace system calls). There a quite a few other exotic and experimental tools available but there seemed to me there was a gap in the coverage...

Recently, I had cause to need an application-level trace. For the problem at hand, I didn't care a hoot about system calls or indeed library calls -  I wanted a trace log file that showed a call to "main", and then entries for all the other functions I had written in the application. A quick search around didn't reveal much, but some lateral thinking saved the day. What tool can display application-level function names? gdb of course! The question was how to coerce it into working as a trace tool. It's actually very simple. What you do is this:

  1. Set breakpoints on every function in your application.
  2. Make GDB display the frame whenever a breakpoint is hit and then continue.
And so was born.

To run it, you need:

  • a directory containing the unpacked source code for your application.
  • a version of your application built with symbols ("gcc -g").
 For example:

$ -d $HOME/src/c/myapp/ myapp --some-arg foo

So, assuming a simple application like this:


void func4 (void)

void func3 (void)
  func4 ();

void func2 (void)
  func3 ();

void func (void)
  func2 ();

main (int argc, char *argv[])
  func ();
  exit (0);

Running the commands below...

$ gcc -g -o funcs funcs.c
$ -d . funcs

Will give you output like this:

main (argc=1, argv=0xbfffeea4) at funcs.c:26
 func () at funcs.c:20
 func2 () at funcs.c:15
 func3 () at funcs.c:10
 func4 () at funcs.c:6

Just what I wanted.