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 void test10a(BPatch_thread *appThread, BPatch_image *appImage)
60 * Instrument a function with a BPatch_breakPointExpr.
62 BPatch_Vector<BPatch_point*> *points =
63 appImage->findProcedurePoint("func10_1", BPatch_entry);
65 printf("**Failed** test #10 (BPatch_breakPointExpr)\n");
66 printf(" unable to locate function \"func10_1\".\n");
70 BPatch_breakPointExpr bp;
72 if (appThread->insertSnippet(bp, *points) == NULL) {
73 printf("**Failed** test #10 (BPatch_breakPointExpr)\n");
74 printf(" unable to insert breakpoint snippet\n");
79 void test11(BPatch_thread */*appThread*/, BPatch_image *appImage)
81 #if !defined(rs6000_ibm_aix4_1)
82 // Test getDisplacedInstructions
83 printf("Skipping test #11 (getDisplacedInstructions)\n");
84 printf(" BPatch_point::getDisplacedInstructions not implemented on this platform\n");
86 BPatch_Vector<BPatch_point*> *points =
87 appImage->findProcedurePoint("func11_1", BPatch_entry);
89 printf("**Failed** test #11 (getDisplacedInstructions)\n");
90 printf(" unable to locate function \"func11_1\".\n");
96 int nbytes = (*points)[0]->getDisplacedInstructions(128, buf);
97 if (nbytes < 0 || nbytes > 128) {
98 printf("**Failed** test #11 (getDisplacedInstructions)\n");
99 printf(" getDisplacedInstructions returned a strange number of bytes (%d)\n", nbytes);
102 for (i = 0; i < nbytes; i++) {
103 if (buf[i] != 0) break;
106 printf("**Failed** test #11 (getDisplacedInstructions)\n");
107 printf(" getDisplacedInstructions doesn't seem to have returned any instructions\n");
109 printf("Passed test #11 (getDisplacedInstructions)\n");
113 BPatch_thread *mutatorMAIN(char *pathname, bool useAttach)
115 BPatch_thread *appThread;
118 printf("Starting \"%s\"\n", pathname);
123 child_argv[n++] = pathname;
124 if (useAttach) child_argv[n++] = "-attach";
125 if (debugPrint) child_argv[n++] = "-verbose";
126 child_argv[n] = NULL;
129 int pid = startNewProcess(pathname, child_argv);
130 if (pid < 0 && !expectErrors) {
131 printf("*ERROR*: unable to start tests due to error starting mutatee process\n");
134 appThread = bpatch->attachProcess(pathname, pid);
136 appThread = bpatch->createProcess(pathname, child_argv);
141 void errorFunc(BPatchErrorLevel level, int num, const char **params)
145 const char *msg = bpatch->getEnglishErrorString(num);
146 bpatch->formatErrorString(line, sizeof(line), msg, params);
152 printf("Error (expected) #%d (level %d): %s\n", num, level, line);
154 printf("Error #%d (level %d): %s\n", num, level, line);
159 // main - decide our role and call the correct "main"
161 main(int argc, char *argv[])
164 bool useAttach = false;
167 // Create an instance of the bpatch library
170 bpatch->registerErrorCallback(errorFunc);
173 for (i=1; i < argc; i++) {
174 if (!strcmp(argv[i], "-verbose")) {
176 } else if (!strcmp(argv[i], "-attach")) {
179 fprintf(stderr, "Usage: test1 [-attach] [-verbose]\n");
184 #if defined(sparc_sun_sunos4_1_3)
186 printf("Attach is not supported on this platform.\n");
195 printf("Skipping test #1 (run an executable that does not exist)\n");
196 printf(" not relevant with -attach option\n");
198 // try to run a program that does not exist
200 ret = mutatorMAIN("./noSuchFile", useAttach);
201 if (ret || !gotError) {
203 printf("**Failed** test #1 (run an executable that does not exist)\n");
205 printf(" created a thread handle for a non-existant file\n");
207 printf(" the error callback should have been called but wasn't\n");
209 printf("Passed test #1 (run an executable that does not exist)\n");
213 // try to run a files that is not a valid program
215 #ifdef i386_unknown_nt4_0
216 ret = mutatorMAIN("nul:", false);
218 ret = mutatorMAIN("/dev/null", false);
220 if (ret || !gotError) {
221 printf("**Failed** test #2 (try to execute a file that is not a valid program)\n");
224 printf(" created a thread handle for invalid executable\n");
226 printf(" the error callback should have been called but wasn't\n");
228 printf("Passed test #2 (try to execute a file that is not a valid program)\n");
231 #if defined(sparc_sun_sunos4_1_3)
232 printf("Skipping test #3 (attach to an invalid pid)\n");
233 printf("Skipping test #4 (attach to a protected pid)\n");
234 printf(" attach is not supported on this platform\n");
236 // attach to an an invalid pid
238 ret = bpatch->attachProcess(MUTATEE_NAME, 65539);
239 if (ret || !gotError) {
240 printf("**Failed** test #3 (attach to an invalid pid)\n");
243 printf(" created a thread handle for invalid executable\n");
245 printf(" the error callback should have been called but wasn't\n");
247 printf("Passed test #3 (attach to an invalid pid)\n");
250 // attach to an a protected pid
252 ret = bpatch->attachProcess(MUTATEE_NAME, 1);
253 if (ret || !gotError) {
254 printf("**Failed** test #4 (attach to a protected pid)\n");
257 printf(" created a thread handle for invalid executable\n");
259 printf(" the error callback should have been called but wasn't\n");
261 printf("Passed test #4 (attach to a protected pid)\n");
265 // Finished trying failure cases
266 expectErrors = false;
268 // now start a real program
270 ret = mutatorMAIN(MUTATEE_NAME, false);
271 if (!ret || gotError) {
272 printf("*ERROR*: unable to create handle for executable\n");
276 BPatch_image *img = ret->getImage();
279 BPatch_function *func = img->findFunction("NoSuchFunction");
280 if (func || !gotError) {
281 printf("**Failed** test #5 (look up nonexistent function)\n");
284 printf(" non-null for findFunction on non-existant func\n");
286 printf(" the error callback should have been called but wasn't\n");
288 printf("Passed test #5 (look up nonexistent function)\n");
293 ret->continueExecution();
295 #if !defined(sparc_sun_solaris2_4)
296 printf("Skipping test #6 (load a dynamically linked library from the mutatee)\n");
297 printf(" feature not implemented on this platform\n");
299 printf("Skipping test #7 (load a dynamically linked library from the mutator)\n");
300 printf(" feature not implemented on this platform\n");
302 waitUntilStopped(ret, 6, "load a dynamically linked library");
304 // see if the dlopen happended.
306 BPatch_Vector<BPatch_module *> *m = img->getModules();
307 for (i=0; i < m->size(); i++) {
309 (*m)[i]->getName(name, sizeof(name));
310 if (strcmp(name, TEST_DYNAMIC_LIB) == 0) {
316 printf("Passed test #6 (load a dynamically linked library from the mutatee)\n");
318 printf("**Failed** test #6 (load a dynamically linked library from the mutatee)\n");
319 printf(" image::getModules() did not indicate that the library had been loaded\n");
323 // make our own dlopen call
324 if (!ret->loadLibrary(TEST_DYNAMIC_LIB2)) {
325 printf("**Failed** test #7 (load a dynamically linked library from the mutator)\n");
326 printf(" BPatch_thread::loadLibrary returned an error\n");
331 BPatch_Vector<BPatch_module *> *m = img->getModules();
332 for (i=0; i < m->size(); i++) {
334 (*m)[i]->getName(name, sizeof(name));
335 if (strcmp(name, TEST_DYNAMIC_LIB2) == 0) {
341 printf("Passed test #7 (load a dynamically linked library from the mutator)\n");
343 printf("**Failed** test #7 (load a dynamically linked library from the mutator)\n");
344 printf(" image::getModules() did not indicate that the library had been loaded\n");
349 ret->continueExecution();
352 ret->stopExecution();
354 #ifndef sparc_sun_sunos4_1_3
355 printf("Skipping test #8 (dump core but do not terminate)\n");
356 printf(" BPatch_thread::dumpCore not implemented on this platform\n");
358 // dump core, but do not terminate.
359 // this doesn't seem to do anything - jkh 7/12/97
360 if (access("mycore", F_OK) == 0) {
361 printf("File \"mycore\" exists. Deleting it.\n");
362 if (unlink("mycore") != 0) {
363 printf("Couldn't delete the file \"mycore\". Exiting.\n");
369 ret->dumpCore("mycore", true);
370 bool coreExists = (access("mycore", F_OK) == 0);
371 if (gotError || !coreExists) {
372 printf("**Failed** test #8 (dump core but do not terminate)\n");
375 printf(" error reported by dumpCore\n");
377 printf(" the core file wasn't written\n");
379 printf("Passed test #8 (dump core but do not terminate)\n");
383 // #if !defined(rs6000_ibm_aix4_1) && !defined(sparc_sun_sunos4_1_3)
385 printf("Skipping test #9 (dump image)\n");
386 printf(" BPatch_thread::dumpImage not implemented on this platform\n");
389 if (access("myimage", F_OK) == 0) {
390 printf("File \"myimage\" exists. Deleting it.\n");
391 if (unlink("myimage") != 0) {
392 printf("Couldn't delete the file \"myimage\". Exiting.\n");
398 ret->dumpImage("myimage");
399 bool imageExists = (access("myimage", F_OK) == 0);
400 if (gotError || !imageExists) {
401 printf("**Failed** test #9 (dump image)\n");
404 printf(" error reported by dumpImage\n");
406 printf(" the image file wasn't written\n");
408 printf("Passed test #9 (dump image)\n");
412 // Wait for process to hit breakpoint
413 waitUntilStopped(ret, 10, "BPatch_breakPointExpr");
414 // waitUntilStopped would not return is we didn't stop
415 printf("Passed test #10 (BPatch_breakPointExpr)\n");
417 // Test getDisplacedInstructions
420 /**********************************************************************
421 * Kill process and make sure it goes away
422 **********************************************************************/
424 int pid = ret->getPid();
426 #ifndef i386_unknown_nt4_0 /* Not yet implemented on NT. */
427 // detach from the process.
431 // now kill the process.
432 #ifdef i386_unknown_nt4_0
433 HANDLE h = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
435 TerminateProcess(h, 0);
443 bool failed_this = false;
444 BPatch_Vector<BPatch_thread *> *threads = bpatch->getThreads();
445 for (i=0; i < threads->size(); i++) {
446 if ((*threads)[i] == ret) {
447 printf("**Failed** test #12 (delete thread)\n"); // LAST TEST
448 printf(" thread %d was deleted, but getThreads found it\n",
456 printf("Passed test #12 (delete thread)\n"); // LAST TEST
462 printf("**Failed** tests\n");
464 printf("Passed all tests\n");