4 // libdyninst validation suite test #2
5 // Author: Jeff Hollingsworth (7/10/97)
8 // This program tests the error features of the dyninst API.
9 // The mutatee that goes with this file is test2.mutatee.c
11 // Naming conventions:
12 // All functions, variables, etc are name funcXX_YY, exprXX_YY, etc.
13 // XX is the test number
14 // YY is the instance withing the test
15 // func1_2 is the second function used in test case #1.
21 #ifdef i386_unknown_nt4_0
23 #define WIN32_LEAN_AND_MEAN
30 #include "BPatch_Vector.h"
31 #include "BPatch_thread.h"
32 #include "BPatch_snippet.h"
33 #include "test_util.h"
36 #ifdef i386_unknown_nt4_0
37 #define access _access
38 #define unlink _unlink
42 #ifdef i386_unknown_nt4_0
43 #define MUTATEE_NAME "test2.mutatee.exe"
45 #define MUTATEE_NAME "./test2.mutatee"
49 bool expectErrors = false;
50 bool gotError = false;
54 // control debug printf statements
55 #define dprintf if (debugPrint) printf
57 BPatch_thread *mutatorMAIN(char *pathname, bool useAttach)
59 BPatch_thread *appThread;
62 printf("Starting \"%s\"\n", pathname);
67 child_argv[n++] = pathname;
68 if (useAttach) child_argv[n++] = "-attach";
69 if (debugPrint) child_argv[n++] = "-verbose";
73 int pid = startNewProcess(pathname, child_argv);
74 if (pid < 0 && !expectErrors) {
75 printf("*ERROR*: unable to start tests due to error starting mutatee process\n");
78 appThread = bpatch->attachProcess(pathname, pid);
80 appThread = bpatch->createProcess(pathname, child_argv);
85 void errorFunc(BPatchErrorLevel level, int num, const char **params)
89 const char *msg = bpatch->getEnglishErrorString(num);
90 bpatch->formatErrorString(line, sizeof(line), msg, params);
96 printf("Error (expected) #%d (level %d): %s\n", num, level, line);
98 printf("Error #%d (level %d): %s\n", num, level, line);
103 // main - decide our role and call the correct "main"
105 main(int argc, char *argv[])
108 bool useAttach = false;
111 // Create an instance of the bpatch library
114 bpatch->registerErrorCallback(errorFunc);
117 for (i=1; i < argc; i++) {
118 if (!strcmp(argv[i], "-verbose")) {
120 } else if (!strcmp(argv[i], "-attach")) {
123 fprintf(stderr, "Usage: test1 [-attach] [-verbose]\n");
128 #if defined(sparc_sun_sunos4_1_3)
130 printf("Attach is not supported on this platform.\n");
139 printf("Skipping test #1 (run an executable that does not exist)\n");
140 printf(" not relevant with -attach option\n");
142 // try to run a program that does not exist
144 ret = mutatorMAIN("./noSuchFile", useAttach);
145 if (ret || !gotError) {
147 printf("**Failed** test #1 (run an executable that does not exist)\n");
149 printf(" created a thread handle for a non-existant file\n");
151 printf(" the error callback should have been called but wasn't\n");
153 printf("Passed test #1 (run an executable that does not exist)\n");
157 // try to run a files that is not a valid program
159 #ifdef i386_unknown_nt4_0
160 ret = mutatorMAIN("nul:", false);
162 ret = mutatorMAIN("/dev/null", false);
164 if (ret || !gotError) {
165 printf("**Failed** test #2 (try to execute a file that is not a valid program)\n");
168 printf(" created a thread handle for invalid executable\n");
170 printf(" the error callback should have been called but wasn't\n");
172 printf("Passed test #2 (try to execute a file that is not a valid program)\n");
175 #if defined(sparc_sun_sunos4_1_3)
176 printf("Skipping test #3 (attach to an invalid pid)\n");
177 printf("Skipping test #4 (attach to a protected pid)\n");
178 printf(" attach is not supported on this platform\n");
180 // attach to an an invalid pid
182 ret = bpatch->attachProcess(MUTATEE_NAME, 65539);
183 if (ret || !gotError) {
184 printf("**Failed** test #3 (attach to an invalid pid)\n");
187 printf(" created a thread handle for invalid executable\n");
189 printf(" the error callback should have been called but wasn't\n");
191 printf("Passed test #3 (attach to an invalid pid)\n");
194 // attach to an a protected pid
196 ret = bpatch->attachProcess(MUTATEE_NAME, 1);
197 if (ret || !gotError) {
198 printf("**Failed** test #4 (attach to a protected pid)\n");
201 printf(" created a thread handle for invalid executable\n");
203 printf(" the error callback should have been called but wasn't\n");
205 printf("Passed test #4 (attach to a protected pid)\n");
209 // Finished trying failure cases
210 expectErrors = false;
212 // now start a real program
214 ret = mutatorMAIN(MUTATEE_NAME, false);
215 if (!ret || gotError) {
216 printf("*ERROR*: unable to create handle for executable\n");
220 BPatch_image *img = ret->getImage();
223 BPatch_function *func = img->findFunction("NoSuchFunction");
224 if (func || !gotError) {
225 printf("**Failed** test #5 (look up nonexistent function)\n");
228 printf(" non-null for findFunction on non-existant func\n");
230 printf(" the error callback should have been called but wasn't\n");
232 printf("Passed test #5 (look up nonexistent function)\n");
235 ret->continueExecution();
237 #ifndef sparc_sun_solaris2_4
238 printf("Skipping test #6 (load a dynamically linked library)\n");
239 printf(" feature not implemented on this platform\n");
241 waitUntilStopped(ret, 6, "load a dynamically linked library");
243 // see if the dlopen happended.
245 BPatch_Vector<BPatch_module *> *m = img->getModules();
246 for (i=0; i < m->size(); i++) {
248 (*m)[i]->getName(name, sizeof(name));
249 if (strcmp(name, TEST_DYNAMIC_LIB) == 0) {
255 printf("Passed test #6 (load a dynamically linked library)\n");
257 printf("**Failed** test #6 (load a dynamically linked library)\n");
258 printf(" image::getModules() did not indicate that the library had been loaded\n");
262 ret->continueExecution();
265 ret->stopExecution();
267 #ifndef sparc_sun_sunos4_1_3
268 printf("Skipping test #7 (dump core but do not terminate)\n");
269 printf(" BPatch_thread::dumpCore() not implemented on this platform\n");
271 // dump core, but do not terminate.
272 // this doesn't seem to do anything - jkh 7/12/97
273 if (access("mycore", F_OK) == 0) {
274 printf("File \"mycore\" exists. Deleting it.\n");
275 if (unlink("mycore") != 0) {
276 printf("Couldn't delete the file \"mycore\". Exiting.\n");
282 ret->dumpCore("mycore", true);
283 bool coreExists = (access("mycore", F_OK) == 0);
284 if (gotError || !coreExists) {
285 printf("**Failed** test #7 (dump core but do not terminate)\n");
288 printf(" error reported by dumpCore\n");
290 printf(" the core file wasn't written\n");
292 printf("Passed test #7 (dump core but do not terminate)\n");
296 #if !defined(rs6000_ibm_aix4_1) && !defined(sparc_sun_sunos4_1_3)
297 printf("Skipping test #8 (dump image)\n");
298 printf(" BPatch_thread::dumpImage() not implemented on this platform\n");
301 if (access("myimage", F_OK) == 0) {
302 printf("File \"myimage\" exists. Deleting it.\n");
303 if (unlink("myimage") != 0) {
304 printf("Couldn't delete the file \"myimage\". Exiting.\n");
310 ret->dumpImage("myimage");
311 bool imageExists = (access("myimage", F_OK) == 0);
312 if (gotError || !imageExists) {
313 printf("**Failed** test #8 (dump image)\n");
316 printf(" error reported by dumpImage\n");
318 printf(" the image file wasn't written\n");
320 printf("Passed test #8 (dump image)\n");
324 int pid = ret->getPid();
326 #ifndef i386_unknown_nt4_0 /* Not yet implemented on NT. */
327 // detach from the process.
331 // now kill the process.
332 #ifdef i386_unknown_nt4_0
333 HANDLE h = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
335 TerminateProcess(h, 0);
343 BPatch_Vector<BPatch_thread *> *threads = bpatch->getThreads();
344 for (i=0; i < threads->size(); i++) {
345 if ((*threads)[i] == ret) {
346 printf("**Failed** test #7 (delete thread)\n");
347 printf(" thread %d was deleted, but getThreads found it\n",
356 printf("**Failed** tests\n");
358 printf("Passed all tests\n");