1#include <stdlib.h>
2#include <stdio.h>
3#include <valgrind.h>
4
5void (*fnptr[256])(char*, char*);
6
7#define BODY(f)                                 \
8{                                               \
9   fprintf(stderr, f);                          \
10   calls++;                                     \
11   (*fnptr[(int)*calls])(calls,seq);            \
12}
13
14void 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)
25BODY("a")
26
27__attribute__((noinline)) void f_b(char *calls, char*seq)
28BODY("b")
29
30__attribute__((noinline)) void f_c(char *calls, char*seq)
31BODY("c");
32
33__attribute__((noinline)) void f_d(char *calls, char*seq)
34BODY("d");
35
36void 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
47int 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