#include <stdlib.h> #include <stdio.h> #include <valgrind.h> void (*fnptr[256])(char*, char*); #define BODY(f) \ { \ fprintf(stderr, f); \ calls++; \ (*fnptr[(int)*calls])(calls,seq); \ } void stacktrace(char*last, char* callsequence) { fprintf(stderr, "\n"); VALGRIND_PRINTF_BACKTRACE ("%s", callsequence); } __attribute__((noinline)) void f_a(char *calls, char*seq); __attribute__((noinline)) void f_b(char *calls, char*seq); __attribute__((noinline)) void f_c(char *calls, char*seq); __attribute__((noinline)) void f_d(char *calls, char*seq); __attribute__((noinline)) void f_a(char *calls, char*seq) BODY("a") __attribute__((noinline)) void f_b(char *calls, char*seq) BODY("b") __attribute__((noinline)) void f_c(char *calls, char*seq) BODY("c"); __attribute__((noinline)) void f_d(char *calls, char*seq) BODY("d"); void doit (int argc, char**argv) { int i; for (i = 1; i < argc; i++) { char* calls = argv[i]; char* seq = argv[i]; calls--; BODY("test ") } } int main(int argc, char**argv) { fnptr[0] = stacktrace; fnptr['a'] = f_a; fnptr['b'] = f_b; fnptr['c'] = f_c; fnptr['d'] = f_d; doit(argc, argv); // with default value of our argument. (void) VALGRIND_MONITOR_COMMAND("v.set merge-recursive-frames 3"); doit(argc, argv); (void) VALGRIND_MONITOR_COMMAND("v.set merge-recursive-frames 2"); doit(argc, argv); (void) VALGRIND_MONITOR_COMMAND("v.set merge-recursive-frames 1"); doit(argc, argv); (void) VALGRIND_MONITOR_COMMAND("v.set merge-recursive-frames 0"); doit(argc, argv); return 0; }