Added copyright text - - - - - - - - - - - - - - - - - - - - - - - - - -
[dyninst.git] / dyninstAPI / tests / src / test4a.mutatee.c
1 /*
2  * Copyright (c) 1996-2004 Barton P. Miller
3  * 
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as "Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  * 
11  * This license is for research uses.  For such uses, there is no
12  * charge. We define "research use" to mean you may freely use it
13  * inside your organization for whatever purposes you see fit. But you
14  * may not re-distribute Paradyn or parts of Paradyn, in any form
15  * source or binary (including derivatives), electronic or otherwise,
16  * to any other organization or entity without our permission.
17  * 
18  * (for other uses, please contact us at paradyn@cs.wisc.edu)
19  * 
20  * All warranties, including without limitation, any warranty of
21  * merchantability or fitness for a particular purpose, are hereby
22  * excluded.
23  * 
24  * By your use of Paradyn, you understand and agree that we (or any
25  * other person or entity with proprietary rights in Paradyn) are
26  * under no obligation to provide either maintenance services,
27  * update services, notices of latent defects, or correction of
28  * defects for Paradyn.
29  * 
30  * Even if advised of the possibility of such damages, under no
31  * circumstances shall we (or any other person or entity with
32  * proprietary rights in the software licensed hereunder) be liable
33  * to you or any third party for direct, indirect, or consequential
34  * damages of any character regardless of type of action, including,
35  * without limitation, loss of profits, loss of use, loss of good
36  * will, or computer failure or malfunction.  You agree to indemnify
37  * us (and any other person or entity with proprietary rights in the
38  * software licensed hereunder) for any and all liability it may
39  * incur to third parties resulting from your use of Paradyn.
40  */
41
42 /* Test application (Mutatee) */
43
44 /* $Id: test4a.mutatee.c,v 1.8 2004/03/23 19:11:30 eli Exp $ */
45
46 #include <stdio.h>
47 #include <assert.h>
48 #include <sys/types.h>
49 #include <signal.h>
50 #include <string.h>
51 #include <stdlib.h>
52 #include <stdarg.h>
53
54 #if defined(i386_unknown_nt4_0) && !defined(__GNUC__)
55 #define WIN32_LEAN_AND_MEAN
56 #include <windows.h>
57 #include <process.h>
58 #define getpid _getpid
59 #else
60 #include <unistd.h>
61 #endif
62
63 #ifdef __cplusplus
64 int mutateeCplusplus = 1;
65 #else
66 int mutateeCplusplus = 0;
67 #endif
68
69 #ifndef COMPILER
70 #define COMPILER ""
71 #endif
72 const char *Builder_id=COMPILER; /* defined on compile line */
73
74 int debugPrint = 0;
75
76 /* control debug printf statements */
77 void dprintf(const char *fmt, ...) {
78    va_list args;
79    va_start(args, fmt);
80
81    if(debugPrint)
82       vfprintf(stderr, fmt, args);
83
84    va_end(args);
85
86    fflush(stderr);
87 }
88
89 #define TRUE    1
90 #define FALSE   0
91
92 int runAllTests = TRUE;
93 #define MAX_TEST 5
94 int runTest[MAX_TEST+1];
95
96 unsigned int globalVariable1_1 = 0xdeadbeef;
97 unsigned int globalVariable2_1 = 0xdeadbeef;
98
99 void func1_1()
100 {
101     globalVariable1_1 = 1000001;
102     exit((int) getpid());
103 }
104
105 /* should be called by parent */
106 void func2_3()
107 {
108     dprintf("pid %d in func2_3\n", (int) getpid());
109     globalVariable2_1 = 2000002;
110 }
111
112 /* should be called by child */
113 void func2_4()
114 {
115     dprintf("pid %d in func2_4\n", (int) getpid());
116     globalVariable2_1 = 2000003;
117 }
118
119 void func2_2() {
120     /* if we get this value at exit, no function was called */
121     globalVariable2_1 = 2000001;
122 }
123
124 void func2_1()
125 {
126 #ifndef i386_unknown_nt4_0
127     int pid;
128
129     pid = fork();
130     if (pid >= 0) {
131         /* both parent and child exit here */
132         func2_2();
133         dprintf("at exit of %d, globalVariable2_1 = %d\n", (int) getpid(),
134                 globalVariable2_1);
135         exit(getpid());
136     } else if (pid < 0) {
137         /* error case */
138         exit(pid);
139     }
140 #endif
141 }
142
143 unsigned int globalVariable3_1 = 0xdeadbeef;
144
145 void func3_1(int argc, char *argv[])
146 {
147     int i;
148     char *ch;
149     char **newArgv;
150
151     newArgv = (char **) calloc(sizeof(char *), argc +1);
152     for (i = 0; i < argc; i++) newArgv[i] = argv[i];
153
154     /* replace 4a in copy of myName by 4b */
155     newArgv[0] = strdup(argv[0]);
156     for (ch=newArgv[0]; *ch; ch++) {
157         if (!strncmp(ch, "4a", 2)) *(ch+1) = 'b';
158     }
159
160     globalVariable3_1 = 3000001;
161     dprintf("Starting \"%s\"\n", newArgv[0]);
162     execvp(newArgv[0], newArgv);
163     perror("execvp");
164 }
165
166 unsigned int globalVariable4_1 = 0xdeadbeef;
167
168 void func4_3()
169 {
170     dprintf("in func4_3\n");
171     globalVariable4_1 = 4000002;
172 }
173
174 void func4_2()
175 {
176     dprintf("in func4_2\n");
177     /* call to func4_3 should be inserted here */
178 }
179
180 void func4_1(int argc, char *argv[])
181 {
182 #ifndef i386_unknown_nt4_0
183     int i;
184     int pid;
185     char *ch;
186     char **newArgv;
187
188     pid = fork();
189     if (pid == 0) {
190         newArgv = (char**) calloc(sizeof(char *), argc +1);
191         for (i = 0; i < argc; i++) newArgv[i] = argv[i];
192         
193         /* replace 4a in copy of myName by 4b */
194         newArgv[0] = strdup(argv[0]);
195         for (ch=newArgv[0]; *ch; ch++) {
196             if (!strncmp(ch, "4a", 2)) *(ch+1) = 'b';
197         }
198         
199         globalVariable3_1 = 3000001;
200         dprintf("Starting \"%s\"\n", newArgv[0]);
201         execvp(newArgv[0], newArgv);
202         perror("execvp");
203     } else {
204         func4_2();
205 #if defined(rs6000_ibm_aix4_1)
206         /* On AIX the child dies when the parent exits, so wait */
207         sleep(3);
208 #endif
209         exit(getpid());
210     }
211 #endif
212 }
213
214 int main(int argc, char *argv[])
215 {                                       
216     int i, j;
217
218     for (i=1; i < argc; i++) {
219         if (!strcmp(argv[i], "-verbose")) {
220             debugPrint = TRUE;
221         } else if (!strcmp(argv[i], "-run")) {
222             runAllTests = FALSE;
223             for (j=0; j <= MAX_TEST; j++) runTest[j] = FALSE;
224             for (j=i+1; j < argc; j++) {
225                 unsigned int testId;
226                 if ((testId = atoi(argv[j]))) {
227                     if ((testId > 0) && (testId <= MAX_TEST)) {
228                         runTest[testId] = TRUE;
229                     } else {
230                         printf("invalid test %d requested\n", testId);
231                         exit(-1);
232                     }
233                 } else {
234                     /* end of test list */
235                     break;
236                 }
237             }
238             i=j-1;
239         } else {
240             fprintf(stderr, "Usage: %s [-verbose] -run <num> ..\n", argv[0]);
241             exit(-1);
242         }
243     }
244
245     if ((argc==1) || debugPrint)
246         printf("Mutatee %s [%s]:\"%s\"\n", argv[0], 
247                 mutateeCplusplus ? "C++" : "C", Builder_id);
248     if (argc==1) exit(0);
249
250     if (runTest[1]) func1_1();
251     if (runTest[2]) func2_1();
252     if (runTest[3]) func3_1(argc, argv);
253     if (runTest[4]) func4_1(argc, argv);
254
255     dprintf("Mutatee %s terminating.\n", argv[0]);
256     return 0;
257 }