1 #include <stdlib.h> 2 #include <stdio.h> 3 #include <valgrind.h> 4 5 void (*fnptr[256])(char*, char*); 6 7 #define BODY(f) \ 8 { \ 9 fprintf(stderr, f); \ 10 calls++; \ 11 (*fnptr[(int)*calls])(calls,seq); \ 12 } 13 14 void stacktrace(char*last, char* callsequence) 15 { 16 fprintf(stderr, "\n"); 17 VALGRIND_PRINTF_BACKTRACE ("%s", callsequence); 18 } 19 __attribute__((noinline)) void f_a(char *calls, char*seq); 20 __attribute__((noinline)) void f_b(char *calls, char*seq); 21 __attribute__((noinline)) void f_c(char *calls, char*seq); 22 __attribute__((noinline)) void f_d(char *calls, char*seq); 23 24 __attribute__((noinline)) void f_a(char *calls, char*seq) 25 BODY("a") 26 27 __attribute__((noinline)) void f_b(char *calls, char*seq) 28 BODY("b") 29 30 __attribute__((noinline)) void f_c(char *calls, char*seq) 31 BODY("c"); 32 33 __attribute__((noinline)) void f_d(char *calls, char*seq) 34 BODY("d"); 35 36 void doit (int argc, char**argv) 37 { 38 int i; 39 for (i = 1; i < argc; i++) { 40 char* calls = argv[i]; 41 char* seq = argv[i]; 42 calls--; 43 BODY("test ") 44 } 45 } 46 47 int main(int argc, char**argv) 48 { 49 50 fnptr[0] = stacktrace; 51 fnptr['a'] = f_a; 52 fnptr['b'] = f_b; 53 fnptr['c'] = f_c; 54 fnptr['d'] = f_d; 55 56 doit(argc, argv); // with default value of our argument. 57 58 (void) VALGRIND_MONITOR_COMMAND("v.set merge-recursive-frames 3"); 59 doit(argc, argv); 60 61 (void) VALGRIND_MONITOR_COMMAND("v.set merge-recursive-frames 2"); 62 doit(argc, argv); 63 64 (void) VALGRIND_MONITOR_COMMAND("v.set merge-recursive-frames 1"); 65 doit(argc, argv); 66 67 (void) VALGRIND_MONITOR_COMMAND("v.set merge-recursive-frames 0"); 68 doit(argc, argv); 69 70 return 0; 71 } 72