1 // $Id: test1.C,v 1.52 2000/03/22 19:08:48 tikir Exp
3 // libdyninst validation suite test #1
4 // Author: Jeff Hollingsworth (1/7/97)
5 // derived from a previous test by Bryan Buck
8 // This program tests the basic features of the dyninst API.
9 // The mutatee that goes with this file is test5.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
29 #include "BPatch_Vector.h"
30 #include "BPatch_thread.h"
31 #include "BPatch_snippet.h"
32 #include "BPatch_flowGraph.h"
33 #include "test_util.h"
35 // #include <vector.h>
38 int debugPrint = 0; // internal "mutator" tracing
39 int errorPrint = 0; // external "dyninst" tracing (via errorFunc)
41 bool forceRelocation = false; // Force relocation upon instrumentation
43 bool runAllTests = true;
44 const unsigned int MAX_TEST = 12;
45 bool runTest[MAX_TEST+1];
46 bool passedTest[MAX_TEST+1];
50 static char *mutateeNameRoot = "test5.mutatee";
52 // control debug printf statements
53 #define dprintf if (debugPrint) printf
55 /**************************************************************************
57 **************************************************************************/
59 void errorFunc(BPatchErrorLevel level, int num, const char **params)
62 // conditional reporting of warnings and informational messages
64 if (level == BPatchInfo)
65 { if (errorPrint > 1) printf("%s\n", params[0]); }
67 printf("%s", params[0]);
70 // reporting of actual errors
72 const char *msg = bpatch->getEnglishErrorString(num);
73 bpatch->formatErrorString(line, sizeof(line), msg, params);
75 printf("Error #%d (level %d): %s\n", num, level, line);
77 // We consider some errors fatal.
84 /**************************************************************************
86 **************************************************************************/
88 // check that the cost of a snippet is sane. Due to differences between
89 // platforms, it is impossible to check this exactly in a machine independent
91 void checkCost(BPatch_snippet snippet)
96 // test copy constructor too.
99 cost = snippet.getCost();
100 dprintf("Snippet cost=%g\n", cost);
102 printf("*Error*: negative snippet cost\n");
103 } else if (cost == 0.0) {
104 printf("*Warning*: zero snippet cost\n");
105 } else if (cost > 0.01) {
106 printf("*Error*: snippet cost of %f, exceeds max expected of 0.1",
112 /**************************************************************************
114 **************************************************************************/
117 // Start Test Case #1 - (C++ argument pass)
119 void mutatorTest1(BPatch_thread *appThread, BPatch_image *appImage)
121 #if defined(sparc_sun_solaris2_4)
122 BPatch_Vector<BPatch_point *> *point1_1 =
123 appImage->findProcedurePoint("arg_test::call_cpp", BPatch_subroutine);
127 // check the paramter passing modes
128 BPatch_variableExpr *arg0 = appImage->findVariable(*(*point1_1)[0],
130 BPatch_variableExpr *arg1 = appImage->findVariable(*(*point1_1)[0],
132 BPatch_variableExpr *arg2 = appImage->findVariable(*(*point1_1)[0],
134 BPatch_variableExpr *arg3 = appImage->findVariable(*(*point1_1)[0],
136 BPatch_variableExpr *arg4 = appImage->findVariable(*(*point1_1)[0],
139 if (!arg0 || !arg1 || !arg2 || !arg3 || !arg4) {
140 fprintf(stderr, "**Failed** test #1 (argument passing)\n");
142 fprintf(stderr, " can't find local variable arg0\n");
144 fprintf(stderr, " can't find local variable arg1\n");
146 fprintf(stderr, " can't find local variable arg2\n");
148 fprintf(stderr, " can't find local variable arg3\n");
150 fprintf(stderr, " can't find local variable arg4\n");
154 BPatch_type *type1_0 = const_cast<BPatch_type *> (arg0->getType());
155 BPatch_type *type1_1 = const_cast<BPatch_type *> (arg1->getType());
156 BPatch_type *type1_2 = const_cast<BPatch_type *> (arg2->getType());
157 BPatch_type *type1_3 = const_cast<BPatch_type *> (arg4->getType());
158 assert(type1_0 && type1_1 && type1_2 && type1_3);
160 if (!type1_1->isCompatible(type1_3)) {
161 fprintf(stderr, "**Failed** test #1 (C++ argument pass)\n");
162 fprintf(stderr," type1_1 reported as incompatibile with type1_3\n");
166 if (!type1_2->isCompatible(type1_0)) {
167 fprintf(stderr, "**Failed** test #1 (C++ argument pass)\n");
168 fprintf(stderr," type1_2 reported as incompatibile with type1_0\n")
173 BPatch_arithExpr expr1_1(BPatch_assign, *arg3, BPatch_constExpr(1));
175 appThread->insertSnippet(expr1_1, *point1_1);
177 // pass a paramter to a class member function
178 BPatch_Vector<BPatch_point *> *point1_2 =
179 appImage->findProcedurePoint("arg_test::func_cpp", BPatch_exit);
180 if (!point1_2 || (point1_2->size() < 1)) {
181 fprintf(stderr, "Unable to find point arg_test::func_cpp - exit.\n");
185 BPatch_function *call1_func = appImage->findFunction("arg_test::arg_pass");
186 if (call1_func == NULL) {
187 fprintf(stderr, "Unable to find function \"cpp_test_util::call_cpp.\"\n");
191 BPatch_variableExpr *this1 = appImage->findVariable("test1");
193 fprintf(stderr, "**Failed** test #1 (C++ argument pass)\n");
194 fprintf(stderr, "Unable to find variable \"test1\"\n");
198 BPatch_Vector<BPatch_snippet *> call1_args;
199 BPatch_constExpr expr1_2((unsigned long)this1->getBaseAddr());
200 call1_args.push_back(&expr1_2);
201 BPatch_constExpr expr1_3(1);
202 call1_args.push_back(&expr1_3);
203 BPatch_funcCallExpr call1Expr(*call1_func, call1_args);
205 checkCost(call1Expr);
206 appThread->insertSnippet(call1Expr, *point1_2);
211 // Start Test Case #2 - (overload function)
213 void mutatorTest2(BPatch_thread *appThread, BPatch_image *appImage)
216 #if defined(sparc_sun_solaris2_4)
217 BPatch_Vector<BPatch_point *> *point2_1 =
218 appImage->findProcedurePoint("overload_func_test::func_cpp", BPatch_subroutine);
219 if (!point2_1 || (point2_1->size() < 2)) {
220 fprintf(stderr, "Unable to find point overload_func_test::func_cpp - calls. \n");
224 for (int n=0; n<point2_1->size(); n++) {
225 BPatch_function *func;
227 if ((func = (*point2_1)[n]->getCalledFunction()) == NULL) continue;
230 if (func->getName(fn, 256) == NULL) {
231 fprintf(stderr, "**Failed** test #2 (overloaded functions)\n");
232 fprintf(stderr, " Can't get name of called function in overload_func_test::func_cpp\n");
235 if (strcmp(fn, "overload_func_test::call_cpp")) {
236 fprintf(stderr, "**Failed** test #2 (overloaded functions)\n");
237 fprintf(stderr, " The called function was named \"%s\""
238 " not \"overload_func_test::call_cpp\"\n", fn);
241 BPatch_Vector<BPatch_point *> *point2_2 = func->findPoint(BPatch_entry);
242 BPatch_Vector<BPatch_localVar *> *param = func->getParams();
243 assert(point2_2 && param);
248 if ( (param->size() == 1) ||
249 ((param->size() == 2) && (!strcmp((*param)[0]->getName(), "this"))) )
250 //First param might be "this"!
253 fprintf(stderr, "**Failed** test #2 (overloaded functions)\n");
254 fprintf(stderr, " The overloaded function has wrong number of parameters\n");
259 if ( (param->size() == 1) ||
260 ((param->size() == 2) && (!strcmp((*param)[0]->getName(), "this"))) )
261 //First param might be "this"!
264 fprintf(stderr, "**Failed** test #2 (overloaded functions)\n");
265 fprintf(stderr, " The overloaded function has wrong number of parameters\n");
270 if ( (param->size() == 2) ||
271 ((param->size() == 3) && (!strcmp((*param)[0]->getName(), "this"))) )
272 //First param might be "this"!
275 fprintf(stderr, "**Failed** test #2 (overloaded functions)\n");
276 fprintf(stderr, " The overloaded function has wrong number of parameters\n");
281 fprintf(stderr, "**Failed** test #2 (overloaded functions)\n");
282 fprintf(stderr, " Incorrect number of subroutine calls from overload_func_test::func_cpp\n");
288 BPatch_Vector<BPatch_point *> *point2_3 =
289 appImage->findProcedurePoint("overload_func_test::func_cpp", BPatch_exit);
290 if (!point2_3 || point2_3->size() <1) {
291 fprintf(stderr, "Unable to find point overload_func_test::func_cpp - exit.\n");
295 BPatch_function *call2_func = appImage->findFunction("cpp_test_util::call_cpp");
296 if (call2_func == NULL) {
297 fprintf(stderr, "Unable to find function \"cpp_test_util::call_cpp.\"\n");
301 BPatch_variableExpr *this2 = appImage->findVariable("test2");
303 fprintf(stderr, "**Failed** test #2 (overloaded functions)\n");
304 fprintf(stderr, "Unable to find variable \"test2\"\n");
308 BPatch_Vector<BPatch_snippet *> call2_args;
309 BPatch_constExpr expr2_0((unsigned long)this2->getBaseAddr());
310 call2_args.push_back(&expr2_0);
311 BPatch_constExpr expr2_1(2);
312 call2_args.push_back(&expr2_1);
313 BPatch_funcCallExpr call2Expr(*call2_func, call2_args);
315 checkCost(call2Expr);
316 appThread->insertSnippet(call2Expr, *point2_3);
321 // Start Test Case #3 - (overload operator)
323 void mutatorTest3(BPatch_thread *appThread, BPatch_image *appImage)
325 BPatch_Vector<BPatch_point *> *point3_1 =
326 appImage->findProcedurePoint("overload_op_test::func_cpp", BPatch_subroutine);
330 BPatch_function *func;
331 while (index < point3_1->size()) {
332 if ((func = (*point3_1)[index]->getCalledFunction()) == NULL) {
333 fprintf(stderr, "**Failed** test #3 (overload operation)\n");
334 fprintf(stderr, " Can't find the overload operator\n");
338 if (!strcmp("overload_op_test::operator++", func->getName(fn, 256)))
343 BPatch_Vector<BPatch_point *> *point3_2 = func->findPoint(BPatch_exit);
346 BPatch_function *call3_1 = appImage->findFunction("overload_op_test_call_cpp");
347 if (call3_1 == NULL) {
348 fprintf(stderr, "Unable to find function \"overload_op_test_call_cpp\"\n");
352 BPatch_Vector<BPatch_snippet *> opArgs;
353 opArgs.push_back(new BPatch_retExpr());
354 BPatch_funcCallExpr call3_1Expr(*call3_1, opArgs);
356 checkCost(call3_1Expr);
357 appThread->insertSnippet(call3_1Expr, *point3_2);
359 // while (tag != 0) {}
363 // Start Test Case #4 - (static member)
365 void mutatorTest4(BPatch_thread *appThread, BPatch_image *appImage)
367 #if defined(sparc_sun_solaris2_4)
369 BPatch_Vector<BPatch_point *> *point4_1 =
370 appImage->findProcedurePoint("static_test::func_cpp", BPatch_subroutine);
374 BPatch_function *func;
375 int bound = point4_1->size();
376 BPatch_Vector<BPatch_variableExpr *> vect4_1;
378 while ((index < bound) && (vect4_1.size() < 2)) {
379 if ((func = (*point4_1)[index]->getCalledFunction()) == NULL) {
380 fprintf(stderr, "**Failed** test #4 (static member)\n");
381 fprintf(stderr, " Can't find the invoked function\n");
386 if (!strcmp("static_test::call_cpp", func->getName(fn, 256))) {
387 BPatch_Vector<BPatch_point *> *point4_2 = func->findPoint(BPatch_exit);
390 // use getComponent to access this "count". However, getComponent is
391 // causing core dump at this point
392 BPatch_variableExpr *var4_1 = appImage->findVariable(*(*point4_2)[0],
395 fprintf(stderr, "**Failed** test #4 (static member)\n");
396 fprintf(stderr, " Can't find static variable count\n");
399 vect4_1.push_back(var4_1);
404 if (2 != vect4_1.size()) {
405 fprintf(stderr, "**Failed** test #4 (static member)\n");
406 fprintf(stderr, " Incorrect size of an vector\n");
409 if (vect4_1[0]->getBaseAddr() != vect4_1[1]->getBaseAddr()) {
410 fprintf(stderr, "**Failed** test #4 (static member)\n");
411 fprintf(stderr, " Static member does not have a same address\n");
415 BPatch_Vector<BPatch_point *> *point4_3 =
416 appImage->findProcedurePoint("static_test::func_cpp", BPatch_exit);
419 BPatch_function *call4_func = appImage->findFunction("static_test_call_cpp");
420 if (call4_func == NULL) {
421 fprintf(stderr, "Unable to find function \"cpp_test_util::call_cpp.\"\n");
425 BPatch_Vector<BPatch_snippet *> call4_args;
426 BPatch_constExpr expr4_0(4);
427 call4_args.push_back(&expr4_0);
428 BPatch_funcCallExpr call4Expr(*call4_func, call4_args);
430 checkCost(call4Expr);
431 appThread->insertSnippet(call4Expr, *point4_3);
438 // Start Test Case #5 - (namespace)
440 void mutatorTest5(BPatch_thread *appThread, BPatch_image *appImage)
442 #if defined(sparc_sun_solaris2_4)
443 BPatch_Vector<BPatch_point *> *point5_1 =
444 appImage->findProcedurePoint("namespace_test::func_cpp", BPatch_exit);
447 BPatch_variableExpr *var1 = appImage->findVariable(*(*point5_1)[0],
449 BPatch_variableExpr *var2 = appImage->findVariable(*(*point5_1)[0],
451 BPatch_variableExpr *var3 = appImage->findVariable(*(*point5_1)[0],
454 if (!var1 || !var2 || !var3) {
455 fprintf(stderr, "**Failed** test #5 (namespace)\n");
457 fprintf(stderr, " can't find local variable local_fn_var\n");
459 fprintf(stderr, " can't find local variable file local_file_var\n");
461 fprintf(stderr, " can't find global variable CPP_DEFLT_ARG\n");
464 BPatch_Vector<BPatch_point *> *point5_2 =
465 appImage->findProcedurePoint("main", BPatch_allLocations);
467 if (!point5_2 || (point5_2->size() < 1)) {
468 fprintf(stderr, "Unable to find point in main.\n");
471 BPatch_variableExpr *expr5_1=appImage->findVariable(*(*point5_2)[0], "test5");
473 fprintf(stderr, "**Failed** test #5 (namespace)\n");
474 fprintf(stderr, " Unable to locate test5 in main\n");
477 BPatch_Vector<BPatch_variableExpr *> *fields = expr5_1->getComponents();
478 if (!fields || fields->size() == 0 ) {
479 fprintf(stderr, "**Failed** test #5 (namespace)\n");
480 fprintf(stderr, " struct lacked correct number of elements\n");
485 while ( index < fields->size() ) {
486 if (!strcmp("class_variable", (*fields)[index]->getName()) ) {
487 BPatch_function *call5_func = appImage->findFunction("cpp_test_util::call_cpp");
488 if (call5_func == NULL) {
489 fprintf(stderr, "**Failed** test #5 (namespace)\n");
490 fprintf(stderr, "Unable to find function \"cpp_test_util::call_cpp.\"\n");
494 BPatch_variableExpr *this5 = appImage->findVariable("test5");
496 fprintf(stderr, "**Failed** test #5 (namespace)\n");
497 fprintf(stderr, "Unable to find variable \"test5\"\n");
501 BPatch_Vector<BPatch_snippet *> call5_args;
503 BPatch_constExpr expr5_0((unsigned long)this5->getBaseAddr());
504 call5_args.push_back(&expr5_0);
505 BPatch_constExpr expr5_1(5);
506 call5_args.push_back(&expr5_1);
507 BPatch_funcCallExpr call5Expr(*call5_func, call5_args);
508 checkCost(call5Expr);
509 appThread->insertSnippet(call5Expr, *point5_1);
514 fprintf(stderr, "**Failed** test #5 (namespace)\n");
515 fprintf(stderr, " Can't find class member variables\n");
521 // Start Test Case #6 - (exception)
523 void mutatorTest6(BPatch_thread *appThread, BPatch_image *appImage)
525 #if defined(sparc_sun_solaris2_4)
527 BPatch_Vector<BPatch_point *> *point6_1 =
528 appImage->findProcedurePoint("exception_test::func_cpp", BPatch_subroutine);
532 BPatch_function *func;
533 int bound = point6_1->size();
535 BPatch_variableExpr *testno = appImage->findVariable(*(*point6_1)[0],
538 fprintf(stderr, "**Failed** test #6 (exception)\n");
539 fprintf(stderr, " Can't find the variable in try branch of exception statement\n");
543 while (index < bound) {
544 if ((func = (*point6_1)[index]->getCalledFunction()) == NULL) {
545 fprintf(stderr, "**Failed** test #6 (exception)\n");
546 fprintf(stderr, " Can't find the invoked function\n");
550 if (!strcmp("sample_exception::response", func->getName(fn, 256))) {
551 BPatch_Vector<BPatch_point *> *point6_2 = func->findPoint(BPatch_exit);
554 BPatch_function *call6_func =
555 appImage->findFunction("exception_test_call_cpp");
556 if (call6_func == NULL) {
557 fprintf(stderr, "Unable to find function \"exception_test_call_cpp.\"\n");
561 BPatch_Vector<BPatch_snippet *> call6_args;
562 BPatch_constExpr expr6_0(6);
563 call6_args.push_back(&expr6_0);
564 BPatch_funcCallExpr call6Expr(*call6_func, call6_args);
566 checkCost(call6Expr);
567 appThread->insertSnippet(call6Expr, *point6_2);
577 // Start Test Case #7 - (template)
579 void mutatorTest7(BPatch_thread *appThread, BPatch_image *appImage)
581 #if defined(sparc_sun_solaris2_4)
582 BPatch_Vector<BPatch_point *> *point7_1 =
583 appImage->findProcedurePoint("template_test::func_cpp", BPatch_subroutine);
588 BPatch_function *func;
589 int bound = point7_1->size();
590 BPatch_variableExpr *content7_1;
591 BPatch_variableExpr *content7_2;
593 while (index < bound) {
594 if ((func = (*point7_1)[index]->getCalledFunction()) == NULL) {
595 fprintf(stderr, "**Failed** test #7 (template)\n");
596 fprintf(stderr, " Can't find the invoked function\n");
601 if (!strcmp("sample_template<int>::content", func->getName(fn, 256))) {
602 BPatch_Vector<BPatch_point *> *point7_2 = func->findPoint(BPatch_entry);
605 content7_1 = appImage->findVariable(*(*point7_2)[0], "ret");
607 fprintf(stderr, "**Failed** test #7 (template)\n");
608 fprintf(stderr, " Can't find local variable ret\n");
612 } else if (!strcmp("sample_template<char>::content", func->getName(fn, 256))) {
614 BPatch_Vector<BPatch_point *> *point7_3 = func->findPoint(BPatch_entry);
617 content7_2 = appImage->findVariable(*(*point7_3)[0], "ret");
619 fprintf(stderr, "**Failed** test #7 (template)\n");
620 fprintf(stderr, " Can't find local variable ret\n");
629 fprintf(stderr, "**Failed** test #7 (template)\n");
633 BPatch_type *type7_0 = appImage->findType("int");
634 BPatch_type *type7_1 = const_cast<BPatch_type *> (content7_1->getType());
635 BPatch_type *type7_2 = appImage->findType("char");
636 BPatch_type *type7_3 = const_cast<BPatch_type *> (content7_2->getType());
638 if (!type7_0->isCompatible(type7_1)) {
639 fprintf(stderr, "**Failed** test #7 (template)\n");
640 fprintf(stderr," type7_0 reported as incompatibile with type7_1\n");
644 if (!type7_2->isCompatible(type7_3)) {
645 fprintf(stderr, "**Failed** test #7 (template)\n");
646 fprintf(stderr," type7_2 reported as incompatibile with type7_3\n");
650 BPatch_Vector<BPatch_point *> *point7_4 =
651 appImage->findProcedurePoint("template_test::func_cpp", BPatch_exit);
654 BPatch_function *call7_func = appImage->findFunction("template_test_call_cpp");
655 if (call7_func == NULL) {
656 fprintf(stderr, "Unable to find function \"cpp_test_util::call_cpp.\"\n");
660 BPatch_Vector<BPatch_snippet *> call7_args;
661 BPatch_constExpr expr7_0(7);
662 call7_args.push_back(&expr7_0);
663 BPatch_funcCallExpr call7Expr(*call7_func, call7_args);
665 checkCost(call7Expr);
666 appThread->insertSnippet(call7Expr, *point7_4);
671 // Start Test Case #8 - (declaration)
673 void mutatorTest8(BPatch_thread *appThread, BPatch_image *appImage)
675 #if defined(sparc_sun_solaris2_4)
676 // Find the exit point to the procedure "func_cpp"
677 BPatch_Vector<BPatch_point *> *point8_1 =
678 appImage->findProcedurePoint("decl_test::func_cpp", BPatch_exit);
679 if (!point8_1 || (point8_1->size() < 1)) {
680 fprintf(stderr, "Unable to find point decl_test::func_cpp - exit.\n");
684 BPatch_Vector<BPatch_point *> *point8_2 =
685 appImage->findProcedurePoint("main", BPatch_allLocations);
687 if (!point8_2 || (point8_2->size() < 1)) {
688 fprintf(stderr, "Unable to find point in main.\n");
692 BPatch_function *call8_func = appImage->findFunction("decl_test::call_cpp");
693 if (call8_func == NULL ) {
694 fprintf(stderr, "**Failed** test #8 (declaration)\n");
695 fprintf(stderr, "Unable to find function \"decl_test::call_cpp\"\n");
699 BPatch_variableExpr *this8 = appImage->findVariable("test8");
701 fprintf(stderr, "**Failed** test #8 (declaration)\n");
702 fprintf(stderr, "Unable to find variable \"test8\"\n");
706 BPatch_Vector<BPatch_snippet *> call8_args;
707 BPatch_constExpr expr8_0((unsigned long)this8->getBaseAddr());
708 call8_args.push_back(&expr8_0);
709 BPatch_constExpr expr8_1(8);
710 call8_args.push_back(&expr8_1);
711 BPatch_funcCallExpr call8Expr(*call8_func, call8_args);
713 // find the variables of different scopes
714 BPatch_variableExpr *expr8_2=appImage->findVariable("CPP_DEFLT_ARG");
715 BPatch_variableExpr *expr8_3=appImage->findVariable(*(*point8_2)[0], "test8");
716 BPatch_variableExpr *expr8_4=appImage->findVariable(*(*point8_1)[0], "CPP_DEFLT_ARG");
717 if (!expr8_2 || !expr8_3 || !expr8_4) {
718 fprintf(stderr, "**Failed** test #8 (delcaration)\n");
719 fprintf(stderr, " Unable to locate one of variables\n");
723 BPatch_Vector<BPatch_variableExpr *> *fields = expr8_3->getComponents();
724 if (!fields || fields->size() == 0 ) {
725 fprintf(stderr, "**Failed** test #8 (declaration)\n");
726 fprintf(stderr, " struct lacked correct number of elements\n");
731 while ( index < fields->size() ) {
733 strcpy(fieldName, (*fields)[index]->getName());
734 if ( !strcmp("CPP_TEST_UTIL_VAR", (*fields)[index]->getName()) ) {
735 dprintf("Inserted snippet2\n");
736 checkCost(call8Expr);
737 appThread->insertSnippet(call8Expr, *point8_1);
742 fprintf(stderr, "**Failed** test #8 (declaration)\n");
743 fprintf(stderr, " Can't find inherited class member variables\n");
748 // Start Test Case #9 - (derivation)
750 void mutatorTest9(BPatch_thread *, BPatch_image *appImage)
752 #if defined(sparc_sun_solaris2_4)
755 // Find the exit point to the procedure "func_cpp"
756 BPatch_Vector<BPatch_point *> *point9_1 =
757 appImage->findProcedurePoint("derivation_test::func_cpp", BPatch_exit);
758 if (!point9_1 || (point9_1->size() < 1)) {
759 fprintf(stderr, "Unable to find point derivation_test::func_cpp - exit.\n");
763 // access inherited class member variables has been examined in the test 8
764 // now let's try to access the inherited class member function.
766 BPatch_Vector<BPatch_point *> *point9_2 =
767 appImage->findProcedurePoint("main", BPatch_allLocations);
769 if (!point9_2 || (point9_2->size() < 1)) {
770 fprintf(stderr, "Unable to find point in main.\n");
774 BPatch_variableExpr *expr9_0=appImage->findVariable(*(*point9_2)[0], "test9");
776 fprintf(stderr, "**Failed** test #9 (derivation)\n");
777 fprintf(stderr, " Unable to locate one of variables\n");
781 BPatch_Vector<BPatch_variableExpr *> *fields = expr9_0->getComponents();
782 if (!fields || fields->size() == 0 ) {
783 fprintf(stderr, "**Failed** test #9 (derivation)\n");
784 fprintf(stderr, " struct lacked correct number of elements\n");
789 while ( index < fields->size() ) {
790 if ( !strcmp("call_cpp", (*fields)[index]->getName()) ) {
798 fprintf(stderr, "**Failed** test #9 (derivation)\n");
799 fprintf(stderr, " Can't find inherited class member functions\n");
805 // Start Test Case #10 - (find standard C++ library)
807 void mutatorTest10(BPatch_thread *appThread, BPatch_image *appImage)
809 #if defined(sparc_sun_solaris2_4) \
810 || defined(i386_unknown_solaris2_5) \
811 || defined(i386_unknown_linux2_0) \
812 || defined(mips_sgi_irix6_4) \
813 || defined(alpha_dec_osf4_0)
816 BPatch_module *modStdC = NULL;
817 BPatch_Vector<BPatch_module *> *mods = appImage->getModules();
819 strcpy(libStdC, "libstdc++");
821 // Lookup the libstdc++.so standard library
822 if (!mods || mods->size() == 0) {
823 fprintf(stderr, "**Failed test #10 (find standard C++ library)\n");
824 fprintf(stderr, " Mutator couldn't search modules of standard library\n");
827 for (int i = 0; i < mods->size() && !(modStdC); i++) {
829 BPatch_module *m = (*mods)[i];
830 m->getName(buf, 1024);
831 if (!strncmp(libStdC, buf, strlen(libStdC)))
835 fprintf(stderr, "**Failed test #10 (find standard C++ library)\n");
836 fprintf(stderr, " Mutator couldn't find shlib in standard library\n");
841 // find ostream::operator<< function in the standard library
842 BPatch_function *func = modStdC->findFunction("ostream::operator<<");
844 fprintf(stderr, "**Failed test #10 (find standard C++ library)\n");
845 fprintf(stderr, " Mutator couldn't find a function in %s\n", libStdC);
853 // Start Test Case #11 - (replace function in standard C++ library)
855 void mutatorTest11(BPatch_thread *appThread, BPatch_image *appImage)
857 // There is no corresponding failure (test2) testing because the only
858 // bad input to replaceFunction is a non-existent BPatch_function.
860 #if defined(sparc_sun_solaris2_4) \
861 || defined(alpha_dec_osf4_0)
864 BPatch_module *modStdC = NULL;
865 BPatch_Vector<BPatch_module *> *mods = appImage->getModules();
867 strcpy(libStdC, "libstdc++");
869 // Lookup the libstdc++.so standard library
870 if (!mods || mods->size() == 0) {
871 fprintf(stderr, "**Failed test #11 (replace function in standard C++ library)\n");
872 fprintf(stderr, " Mutator couldn't search modules of standard library\n");
875 for (int i = 0; i < mods->size() && !(modStdC); i++) {
877 BPatch_module *m = (*mods)[i];
878 m->getName(buf, 1024);
879 if (!strncmp(libStdC, buf, strlen(libStdC)))
883 fprintf(stderr, "**Failed test #11 (replace function in standard C++ library)\n");
884 fprintf(stderr, " Mutator couldn't find shlib in standard library\n");
889 // Replace a shlib function with a shlib function
890 char buf1[64], buf2[64];
892 BPatch_function *func1 = modStdC->findFunction("ostream::operator<<");
893 BPatch_function *func2 = modStdC->findFunction("istream::operator>>");
894 func1->getName(buf1, 64);
895 func2->getName(buf2, 64);
897 if (! func1 || ! func2) {
898 fprintf(stderr, "**Failed test #11 (replace function in standard C++ library)\n");
899 fprintf(stderr, " Mutator couldn't find a function in %s\n", libStdC);
902 if (! appThread->replaceFunction(*func1, *func2)) {
903 fprintf(stderr, "**Failed test #11 (replace function in standard C++ library)\n");
904 fprintf(stderr, " Mutator couldn't replaceFunction (shlib -> shlib)\n");
907 // Replace a shlib function with an a.out function
908 BPatch_function *func3 = appImage->findFunction("stdlib_test2::call_cpp");
910 fprintf(stderr, "**Failed test #11 (replace function in standard C++ library)\n");
911 fprintf(stderr, "Unable to find function \"stdlib_test2::call_cpp\"\n");
914 if (! appThread->replaceFunction(*func1, *func3)) {
915 fprintf(stderr, "**Failed test #11 (replace function in standard C++ library)\n");
916 fprintf(stderr, " Mutator couldn't replaceFunction (shlib -> a.out)\n");
920 // Replace an a.out function with a shlib function
921 if (! appThread->replaceFunction(*func3, *func2) ) {
922 fprintf(stderr, "**Failed test #11 (replace function in standard C++ library)\n");
923 fprintf(stderr, " Mutator couldn't replaceFunction (a.out -> shlib)\n");
931 // Start Test Case #12 - (C++ member function - virtual, const and inline)
933 void mutatorTest12(BPatch_thread *appThread, BPatch_image *appImage)
935 BPatch_Vector<BPatch_point *> *point12_0 =
936 appImage->findProcedurePoint("cpp_test::func2_cpp", BPatch_allLocations);
938 BPatch_Vector<BPatch_point *> *point12_1 =
939 appImage->findProcedurePoint("cpp_test::func_cpp", BPatch_allLocations);
941 BPatch_Vector<BPatch_point *> *point12_2 =
942 appImage->findProcedurePoint("func_test::func_cpp", BPatch_allLocations);
944 BPatch_Vector<BPatch_point *> *point12_3 =
945 appImage->findProcedurePoint("func_test::call_cpp", BPatch_allLocations);
947 if ( !point12_0 || (point12_0->size() < 1) ||
948 !point12_1 || (point12_1->size() < 1) ||
949 !point12_2 || (point12_2->size() < 1) ||
950 !point12_3 || (point12_3->size() < 1) ) {
952 if ( !point12_0 || (point12_0->size() < 1) ) {
953 fprintf(stderr, "**Failed** test #12 (C++ member functions)\n");
954 fprintf(stderr, " Unable to find point in an virtual function \"cpp_test::func2_cpp.\"\n");
956 if ( !point12_1 || (point12_1->size() < 1) ) {
957 fprintf(stderr, "**Warning** test #12 (C++ member functions)\n");
958 fprintf(stderr, " Unable to find point in a pure virtual function \"cpp_test::func_cpp.\"\n");
960 if ( !point12_2 || (point12_2->size() < 1) ) {
961 fprintf(stderr, "**Failed** test #12 (C++ member functions)\n");
962 fprintf(stderr, " Unable to find point in a const function \"func_test::func_cpp.\"\n");
964 if ( !point12_3 || (point12_3->size() < 1) ) {
965 fprintf(stderr, "**Failed** test #12 (C++ member functions)\n");
966 fprintf(stderr, " Unable to find point in an inline function \"func_test::call_cpp.\"\n");
970 for (int n=0; n<point12_2->size(); n++) {
971 BPatch_function *func;
973 if ((func = (*point12_2)[n]->getCalledFunction()) == NULL) continue;
976 if (func->getName(fn, 256) == NULL) {
977 fprintf(stderr, "**Failed** test #12 (C++ member function)\n");
978 fprintf(stderr, " Can't get name of called function in func_test::func_cpp\n");
982 if (! strcmp(fn, "func_test::call_cpp") ) {
983 BPatch_Vector<BPatch_localVar *> *param = func->getParams();
986 if ( param->size() != 0 ) {
987 fprintf(stderr, "**Failed** test #12 (C++ member function)\n");
988 fprintf(stderr, " The inline function is not inlined\n");
992 BPatch_variableExpr *var1 = appImage->findVariable(*(*point12_2)[0],
996 fprintf(stderr, "**Failed** test #12 (C++ member function)\n");
997 fprintf(stderr, " The inline function is not inlined\n");
1004 fprintf(stderr, "**Failed** test #12 (C++ member function)\n");
1005 fprintf(stderr, " Mutator couldn't find inline function in the caller\n");
1009 /*******************************************************************************/
1010 /*******************************************************************************/
1011 /*******************************************************************************/
1013 int mutatorMAIN(char *pathname, bool useAttach)
1015 BPatch_thread *appThread;
1017 // Create an instance of the BPatch library
1018 bpatch = new BPatch;
1020 // Force functions to be relocated
1021 if (forceRelocation) {
1022 bpatch->setForcedRelocation_NP(true);
1025 // Register a callback function that prints any error messages
1026 bpatch->registerErrorCallback(errorFunc);
1028 // Start the mutatee
1029 printf("Starting \"%s\"\n", pathname);
1031 char *child_argv[MAX_TEST+5];
1034 child_argv[n++] = pathname;
1035 if (debugPrint) child_argv[n++] = "-verbose";
1038 child_argv[n++] = "-runall"; // signifies all tests
1040 child_argv[n++] = "-run";
1041 for (unsigned int j=1; j <= MAX_TEST; j++) {
1044 sprintf(str, "%d", j);
1045 child_argv[n++] = strdup(str);
1050 child_argv[n] = NULL;
1053 int pid = startNewProcessForAttach(pathname, child_argv);
1055 printf("*ERROR*: unable to start tests due to error creating mutatee process\n");
1058 dprintf("New mutatee process pid %d started; attaching...\n", pid);
1060 P_sleep(1); // let the mutatee catch its breath for a moment
1061 appThread = bpatch->attachProcess(pathname, pid);
1063 appThread = bpatch->createProcess(pathname, child_argv,NULL);
1066 if (appThread == NULL) {
1067 fprintf(stderr, "Unable to run test program.\n");
1071 // Read the program's image and get an associated image object
1072 BPatch_image *appImage = appThread->getImage();
1074 // Signal the child that we've attached
1076 signalAttached(appThread, appImage);
1080 BPatch_Vector<BPatch_module *> *m = appImage->getModules();
1081 for (i=0; i < m->size(); i++) {
1082 // dprintf("func %s\n", (*m)[i]->name());
1084 BPatch_Vector<BPatch_function *> *p = appImage->getProcedures();
1085 for (i=0; i < p->size(); i++) {
1086 // dprintf("func %s\n", (*p)[i]->name());
1089 if (runTest[1]) mutatorTest1(appThread, appImage);
1090 if (runTest[2]) mutatorTest2(appThread, appImage);
1091 if (runTest[3]) mutatorTest3(appThread, appImage);
1092 if (runTest[4]) mutatorTest4(appThread, appImage);
1093 if (runTest[5]) mutatorTest5(appThread, appImage);
1094 if (runTest[6]) mutatorTest6(appThread, appImage);
1095 if (runTest[7]) mutatorTest7(appThread, appImage);
1096 if (runTest[8]) mutatorTest8(appThread, appImage);
1097 if (runTest[9]) mutatorTest9(appThread, appImage);
1099 // Start of code to continue the process. All mutations made
1100 // above will be in place before the mutatee begins its tests.
1102 dprintf("starting program execution.\n");
1103 appThread->continueExecution();
1105 while (!appThread->isTerminated())
1106 bpatch->waitForStatusChange();
1108 int exitCode = appThread->terminationStatus();
1109 if (exitCode || debugPrint) printf("Mutatee exit code 0x%x\n", exitCode);
1116 // main - decide our role and call the correct "main"
1119 main(unsigned int argc, char *argv[])
1121 char mutateeName[128];
1122 char libRTname[256];
1124 bool N32ABI = false;
1125 bool useAttach = false;
1127 strcpy(mutateeName,mutateeNameRoot);
1130 if (!getenv("DYNINSTAPI_RT_LIB")) {
1131 fprintf(stderr,"Environment variable DYNINSTAPI_RT_LIB undefined:\n"
1132 #if defined(i386_unknown_nt4_0)
1133 " using standard search strategy for libdyninstAPI_RT.dll\n");
1135 " set it to the full pathname of libdyninstAPI_RT\n");
1139 strcpy((char *)libRTname, (char *)getenv("DYNINSTAPI_RT_LIB"));
1142 // by default run all tests
1143 for (i=1; i <= MAX_TEST; i++) {
1145 passedTest[i] = false;
1148 for (i=1; i < argc; i++) {
1149 if (strncmp(argv[i], "-v+", 3) == 0) errorPrint++;
1150 if (strncmp(argv[i], "-v++", 4) == 0) errorPrint++;
1151 if (strncmp(argv[i], "-verbose", 2) == 0) {
1153 } else if (!strcmp(argv[i], "-V")) {
1154 fprintf (stdout, "%s\n", V_libdyninstAPI);
1156 fprintf (stdout, "DYNINSTAPI_RT_LIB=%s\n", libRTname);
1158 } else if (!strcmp(argv[i], "-attach")) {
1160 } else if (!strcmp(argv[i], "-skip")) {
1162 runAllTests = false;
1163 for (j=i+1; j < argc; j++) {
1164 unsigned int testId;
1165 if ((testId = atoi(argv[j]))) {
1166 if ((testId > 0) && (testId <= MAX_TEST)) {
1167 runTest[testId] = false;
1169 printf("invalid test %d requested\n", testId);
1178 } else if (!strcmp(argv[i], "-run")) {
1180 runAllTests = false;
1181 for (j=0; j <= MAX_TEST; j++) runTest[j] = false;
1182 for (j=i+1; j < argc; j++) {
1183 unsigned int testId;
1184 if ((testId = atoi(argv[j]))) {
1185 if ((testId > 0) && (testId <= MAX_TEST)) {
1186 runTest[testId] = true;
1188 printf("invalid test %d requested\n", testId);
1197 } else if (!strcmp(argv[i], "-mutatee")) {
1200 strcat(mutateeName,argv[i]);
1202 strcpy(mutateeName,argv[i]);
1203 #if defined(i386_unknown_nt4_0) || defined(i386_unknown_linux2_0) || defined(sparc_sun_solaris2_4)
1204 } else if (!strcmp(argv[i], "-relocate")) {
1205 forceRelocation = true;
1207 #if defined(mips_sgi_irix6_4)
1208 } else if (!strcmp(argv[i], "-n32")) {
1212 fprintf(stderr, "Usage: test5 "
1213 "[-V] [-verbose] [-attach] "
1214 #if defined(mips_sgi_irix6_4)
1217 "[-mutatee <test5.mutatee>] "
1218 "[-run <test#> <test#> ...] "
1219 "[-skip <test#> <test#> ...]\n");
1220 fprintf(stderr, "%d subtests\n", MAX_TEST);
1226 printf("Running Tests: ");
1227 for (unsigned int j=1; j <= MAX_TEST; j++) {
1228 if (runTest[j]) printf("%d ", j);
1233 // patch up the default compiler in mutatee name (if necessary)
1234 if (!strstr(mutateeName, "_"))
1235 #if defined(i386_unknown_nt4_0)
1236 strcat(mutateeName,"_VC++");
1238 strcat(mutateeName,"_g++");
1240 if (N32ABI || strstr(mutateeName,"_n32")) {
1241 // patch up file names based on alternate ABI (as necessary)
1242 if (!strstr(mutateeName, "_n32")) strcat(mutateeName,"_n32");
1244 // patch up the platform-specific filename extensions
1245 #if defined(i386_unknown_nt4_0)
1246 if (!strstr(mutateeName, ".exe")) strcat(mutateeName,".exe");
1249 int exitCode = mutatorMAIN(mutateeName, useAttach);