Update copyright to LGPL on all files
[dyninst.git] / dyninstAPI / tests / src / test8.mutatee.c
1 /*
2  * Copyright (c) 1996-2009 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  * By your use of Paradyn, you understand and agree that we (or any
12  * other person or entity with proprietary rights in Paradyn) are
13  * under no obligation to provide either maintenance services,
14  * update services, notices of latent defects, or correction of
15  * defects for Paradyn.
16  * 
17  * This library is free software; you can redistribute it and/or
18  * modify it under the terms of the GNU Lesser General Public
19  * License as published by the Free Software Foundation; either
20  * version 2.1 of the License, or (at your option) any later version.
21  * 
22  * This library is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25  * Lesser General Public License for more details.
26  * 
27  * You should have received a copy of the GNU Lesser General Public
28  * License along with this library; if not, write to the Free Software
29  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30  */
31
32 /* Test application (Mutatee) */
33
34 /* $Id: */
35
36 #include <stdio.h>
37 #include <assert.h>
38 #include <sys/types.h>
39 #include <signal.h>
40 #include <string.h>
41 #include <stdlib.h>
42 #include "mutatee_util.h"
43
44 #define do_dyninst_breakpoint() stop_process_()
45
46 #if defined(i386_unknown_nt4_0) && !defined(__GNUC__)
47 #define WIN32_LEAN_AND_MEAN
48 #include <windows.h>
49 #define getpid _getpid
50 #else
51 #include <unistd.h>
52 #include <dlfcn.h>
53 #endif
54
55 #ifdef __cplusplus
56 int mutateeCplusplus = 1;
57 #else
58 int mutateeCplusplus = 0;
59 #endif
60
61 #ifndef COMPILER
62 #define COMPILER ""
63 #endif
64 const char *Builder_id=COMPILER; /* defined on compile line */
65
66 /* control debug printf statements */
67 #define dprintf if (debugPrint) printf
68 int debugPrint = 0;
69
70 #define TRUE    1
71 #define FALSE   0
72
73 int runAllTests = TRUE;
74 #define MAX_TEST 3
75 int runTest[MAX_TEST+1];
76
77 int globalVariable1_1 = 0;
78 int globalVariable2_1 = 0;
79 volatile int globalVariable2_2 = 0;
80
81 void func1_3()
82 {
83     globalVariable1_1++;
84     do_dyninst_breakpoint();
85 }
86
87 void func1_2()
88 {
89     globalVariable1_1++;
90     func1_3();
91 }
92
93 void func1_1()
94 {
95     globalVariable1_1++;
96     func1_2();
97 }
98
99 #if !defined(i386_unknown_nt4_0)
100 void func2_4()
101 {
102     globalVariable2_1++;
103     do_dyninst_breakpoint();
104 }
105
106 void sigalrm_handler(int signum)
107 {
108     globalVariable2_1++;
109     globalVariable2_2 = 1;
110     func2_4();
111 }
112
113 void func2_3()
114 {
115     globalVariable2_1++;
116
117     /* Cause a SIGALRM */
118     alarm(1);
119     while (globalVariable2_2 == 0) ;
120 }
121
122 void func2_2()
123 {
124     globalVariable2_1++;
125     func2_3();
126 }
127 #endif /* !i386_unknown_nt4_0 */
128
129 void func2_1()
130 {
131 #if defined(i386_unknown_linux2_0) \
132  || defined(x86_64_unknown_linux2_4) /* Blind duplication - Ray */ \
133  || defined(sparc_sun_solaris2_4) \
134  || defined(ia64_unknown_linux2_4)
135     void (*old_handler)(int) = signal(SIGALRM, sigalrm_handler);
136
137     globalVariable2_1++;
138     func2_2();
139
140     signal(SIGALRM, old_handler);
141 #endif
142 }
143
144 void func3_4() {
145         ;
146         }
147
148 void func3_3() {
149         do_dyninst_breakpoint();
150         } /* end func3_3() */
151
152 void func3_2() {
153         /* This function will be instrumented to call func3_3, which
154            stops the mutatee and allows the mutator to walk the stack. */
155            
156         /* This is to give us a third place to instrument. */
157         func3_4();
158         } /* end func3_2() */
159         
160 void func3_1() {
161         /* Stop myself.  The mutator will instrument func3_2() at this point. */
162         do_dyninst_breakpoint();
163         
164         /* This function will be instrumented. */
165         func3_2();      
166         } /* end func3_1() */
167
168 int main(int argc, char *argv[])
169 {                                       
170     int i, j;
171
172     for (j=0; j <= MAX_TEST; j++)
173         runTest[j] = TRUE;
174
175     for (i=1; i < argc; i++) {
176         if (!strcmp(argv[i], "-verbose")) {
177             debugPrint = TRUE;
178         } else if (!strcmp(argv[i], "-runall")) {
179             runAllTests = TRUE;
180             for (j=0; j <= MAX_TEST; j++) runTest[j] = TRUE;
181         } else if (!strcmp(argv[i], "-run")) {
182             runAllTests = FALSE;
183             for (j=0; j <= MAX_TEST; j++) runTest[j] = FALSE;
184             for (j=i+1; j < argc; j++) {
185                 unsigned int testId;
186                 if ((testId = atoi(argv[j]))) {
187                     if ((testId > 0) && (testId <= MAX_TEST)) {
188                         runTest[testId] = TRUE;
189                     } else {
190                         printf("invalid test %d requested\n", testId);
191                         exit(-1);
192                     }
193                 } else {
194                     /* end of test list */
195                     break;
196                 }
197             }
198             i=j-1;
199         } else {
200             fprintf(stderr, "Usage: %s [-verbose] -run <num> ..\n", argv[0]);
201             exit(-1);
202         }
203     }
204
205     if ((argc==1) || debugPrint)
206         printf("Mutatee %s [%s]:\"%s\"\n", argv[0], 
207                 mutateeCplusplus ? "C++" : "C", Builder_id);
208     if (argc==1) exit(0);
209
210     if (runTest[1]) func1_1();
211     if (runTest[2]) func2_1();
212         if (runTest[3]) func3_1();
213         
214     fprintf( stderr, "Mutatee %s terminating.\n", argv[0] );
215     return 0;
216 }