File: wrap8.c

package info (click to toggle)
valgrind 1%3A3.3.1-3
  • links: PTS
  • area: main
  • in suites: lenny
  • size: 34,452 kB
  • ctags: 27,778
  • sloc: ansic: 234,398; sh: 14,186; xml: 11,662; perl: 4,410; asm: 3,135; makefile: 3,011; exp: 625; cpp: 255; haskell: 195
file content (140 lines) | stat: -rw-r--r-- 2,932 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#include <unistd.h>
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include "valgrind.h"

/* This is the same as wrap5.c, except that the recursion depth is 16.
   This is intended to check that on ppc64-linux, which uses a
   16-entry per-thread stack, the resulting stack overflow is caught.
   (Undetected overflows in redirection stacks are very bad news; they
   cause guest code to fail in all sorts of strange ways.)

   Hence this test has two expected outcomes:
   - on ppc64-linux, a stack overflow is caught, and V aborts.
   - on everything else, it runs successfully to completion.
   Note, pre() and post() used so as to avoid printf, which messes
   up the call stacks on ppc64-linux due to intercept of mempcpy.
*/
typedef 
   struct _Lard {
      struct _Lard* next; 
      char stuff[999]; 
   }
   Lard;
Lard* lard = NULL;
static int ctr = 0;

void addMoreLard ( void )
{
   Lard* p;
   ctr++;
   if ((ctr % 3) == 1) {
      p = malloc(sizeof(Lard));
      p->next = lard;
      lard = p;
   }
}
static void post ( char* s, int n, int r );
static void pre ( char* s, int n );
static int fact1 ( int n );
static int fact2 ( int n );

/* This is needed to stop gcc4 turning 'fact' into a loop */
__attribute__((noinline))
int mul ( int x, int y ) { return x * y; }

int fact1 ( int n )
{
   addMoreLard();
   if (n == 0) return 1; else return mul(n, fact2(n-1));
}
int fact2 ( int n )
{
   addMoreLard();
   if (n == 0) return 1; else return mul(n, fact1(n-1));
}


int I_WRAP_SONAME_FNNAME_ZU(NONE,fact1) ( int n )
{
   int    r;
   OrigFn fn;
   VALGRIND_GET_ORIG_FN(fn);
   pre("wrapper1", n);
   addMoreLard();
   CALL_FN_W_W(r, fn, n);
   addMoreLard();
   post("wrapper1", n, r);
   if (n >= 3) r += fact2(2);
   return r;
}

int I_WRAP_SONAME_FNNAME_ZU(NONE,fact2) ( int n )
{
   int    r;
   OrigFn fn;
   VALGRIND_GET_ORIG_FN(fn);
   pre("wrapper2", n);
   addMoreLard();
   CALL_FN_W_W(r, fn, n);
   addMoreLard();
   post("wrapper2", n, r);
   return r;
}

/* --------------- */

int main ( void )
{
   int r, n = 15; /* 14 succeeds on ppc64-linux, >= 15 fails */
   Lard *p, *p_next;
   printf("computing fact1(%d)\n", n); fflush(stdout);
   r = fact1(n);
   printf("fact1(%d) = %d\n", n, r); fflush(stdout);

   printf("allocated %d Lards\n", ctr); fflush(stdout);
   for (p = lard; p; p = p_next) {
      p_next = p->next;
      free(p);
   }

   return 0;
}

static void send ( char* s )
{
  while (*s) {
    write(1, s, 1);
    s++;
  }
}

static void pre ( char* s, int n )
{
  char buf[50];
  fflush(stdout);
  sprintf(buf,"%d", n);
  send("in ");
  send(s);
  send("-pre:  fact(");
  send(buf);
  send(")\n");
  fflush(stdout);
}

static void post ( char* s, int n, int r )
{
  char buf[50];
  fflush(stdout);
  sprintf(buf,"%d", n);
  send("in ");
  send(s);
  send("-post: fact(");
  send(buf);
  send(") = ");
  sprintf(buf,"%d", r);
  send(buf);
  send("\n");
  fflush(stdout);
}