Quite often, you may would have come across scenarios where you would want to prepare a trace of your own program and understand what is the execution flow of a particular function in your C program. In this example I will show you how exactly you can do that using DTrace.





Here is a simple C Program which implements two functions (add and sub).


#include
int add(int a, int b);
int sub(int a, int b);
int main()
{
int a;
int b;
int c;
printf("\nEnter A and B: "
scanf("%d%d", &a, &b);
c = add(a, b);
printf ("\n Val - %d", c);

}

int add(int a, int b)
{
return (sub(a, b));

}

int sub(int a, int b)
{
int c = a - b;
return (c);
}



Now I would like to trace the function add in this program and see what functions, in turn, are invoked when add is executed.





DTrace Code:


pid$1:test:$2:entry
{
self->trace = 1;
}

pid$1::$2:return
/self->trace/
{
self->trace = 0;
}

pid$1:::entry,
pid$1:::return
/self->trace/
{
}






I will my binary test (using -o flag) and I will be exacuting this
binary by ./test. In another terminal, I will execute this DTrace
script, which uses the pid provider.
Notice the probe description, the module part of it carries the name of
my program binary (this way only those function calls made in the
context of my program will be traced. If you leave the module part
blank in the probe description, all function calls (including system
calls) will be included in the trace).

Let us compile this application (I am using Sun compiler, you can use gcc as well)

kumar@sunsolaris:~/Desktop$ cc -o test myc.c


Now let us run the DTrace script in another terminal window:


kumar@sunsolaris:~/Desktop$ dtrace -F -s myfunc.d `pgrep test` add






And here is the output:





As you can see, the script tells me that add function calls sub. Just imagine your C application having 1000 functions, and the simplicity that you can bring to the whole debugging process if you can understand the flow with this ease.











Read More about [Using DTrace to profile function flows in your C programs...