drd: Add a consistency check
[valgrind.git] / memcheck / tests / wrap8.c
blob10ac129d3f0541766bb302b593580e92bbd9a1e6
1 #include <unistd.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include "valgrind.h"
6 /* This is the same as wrap5.c, except that the recursion depth is 16.
7 This is intended to check that on ppc64-linux, which uses a
8 16-entry per-thread stack, the resulting stack overflow is caught.
9 (Undetected overflows in redirection stacks are very bad news; they
10 cause guest code to fail in all sorts of strange ways.)
12 Hence this test has two expected outcomes:
13 - on ppc64-linux, a stack overflow is caught, and V aborts.
14 - on everything else, it runs successfully to completion.
15 Note, pre() and post() used so as to avoid printf, which messes
16 up the call stacks on ppc64-linux due to intercept of mempcpy.
18 typedef
19 struct _Lard {
20 struct _Lard* next;
21 char stuff[999];
23 Lard;
24 Lard* lard = NULL;
25 static int ctr = 0;
27 void addMoreLard ( void )
29 Lard* p;
30 ctr++;
31 if ((ctr % 3) == 1) {
32 p = malloc(sizeof(Lard));
33 p->next = lard;
34 lard = p;
37 static void post ( char* s, int n, int r );
38 static void pre ( char* s, int n );
39 static int fact1 ( int n );
40 static int fact2 ( int n );
42 /* This is needed to stop gcc4 turning 'fact' into a loop */
43 __attribute__((noinline))
44 int mul ( int x, int y ) { return x * y; }
46 int fact1 ( int n )
48 addMoreLard();
49 if (n == 0) return 1; else return mul(n, fact2(n-1));
51 int fact2 ( int n )
53 addMoreLard();
54 if (n == 0) return 1; else return mul(n, fact1(n-1));
58 int I_WRAP_SONAME_FNNAME_ZU(NONE,fact1) ( int n )
60 int r;
61 OrigFn fn;
62 VALGRIND_GET_ORIG_FN(fn);
63 pre("wrapper1", n);
64 addMoreLard();
65 CALL_FN_W_W(r, fn, n);
66 addMoreLard();
67 post("wrapper1", n, r);
68 if (n >= 3) r += fact2(2);
69 return r;
72 int I_WRAP_SONAME_FNNAME_ZU(NONE,fact2) ( int n )
74 int r;
75 OrigFn fn;
76 VALGRIND_GET_ORIG_FN(fn);
77 pre("wrapper2", n);
78 addMoreLard();
79 CALL_FN_W_W(r, fn, n);
80 addMoreLard();
81 post("wrapper2", n, r);
82 return r;
85 /* --------------- */
87 int main ( void )
89 int r, n = 15; /* 14 succeeds on ppc64-linux, >= 15 fails */
90 Lard *p, *p_next;
91 printf("computing fact1(%d)\n", n); fflush(stdout);
92 r = fact1(n);
93 printf("fact1(%d) = %d\n", n, r); fflush(stdout);
95 printf("allocated %d Lards\n", ctr); fflush(stdout);
96 for (p = lard; p; p = p_next) {
97 p_next = p->next;
98 free(p);
101 return 0;
104 static void send ( char* s )
106 while (*s) {
107 write(1, s, 1);
108 s++;
112 static void pre ( char* s, int n )
114 char buf[50];
115 fflush(stdout);
116 sprintf(buf,"%d", n);
117 send("in ");
118 send(s);
119 send("-pre: fact(");
120 send(buf);
121 send(")\n");
122 fflush(stdout);
125 static void post ( char* s, int n, int r )
127 char buf[50];
128 fflush(stdout);
129 sprintf(buf,"%d", n);
130 send("in ");
131 send(s);
132 send("-post: fact(");
133 send(buf);
134 send(") = ");
135 sprintf(buf,"%d", r);
136 send(buf);
137 send("\n");
138 fflush(stdout);