Rename newtestsuite to testsuite
[dyninst.git] / testsuite / src / dyninst / test_thread_7.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 #include <BPatch.h>
43 #include <BPatch_process.h>
44 #include <BPatch_thread.h>
45 #include <BPatch_image.h>
46 #include <BPatch_function.h>
47 #include <assert.h>
48 #include <string.h>
49
50 #include "test_lib.h"
51
52 #include "dyninst_comp.h"
53
54 #define MAX_ARGS 32
55
56 class test_thread_7_Mutator : public DyninstMutator {
57 protected:
58   BPatch *bpatch;
59   bool create_proc;
60   char *filename;
61   BPatch_process *proc;
62   char *args[MAX_ARGS];
63   unsigned num_args;
64
65   BPatch_process *getProcess();
66   void instr_func(BPatch_function *func, BPatch_function *lvl1func);
67
68 public:
69   test_thread_7_Mutator();
70   virtual bool hasCustomExecutionPath() { return true; }
71   virtual test_results_t setup(ParameterDict &param);
72   virtual test_results_t executeTest();
73 };
74 extern "C" DLLEXPORT TestMutator *test_thread_7_factory() {
75   return new test_thread_7_Mutator();
76 }
77
78 test_thread_7_Mutator::test_thread_7_Mutator()
79   : bpatch(NULL), create_proc(true), filename(NULL), num_args(0) {
80 }
81
82 // static FILE *outlog = NULL;
83 // static FILE *errlog = NULL;
84
85
86 static bool debug_flag = false;
87 #define dprintf if (debug_flag) fprintf
88
89 void test_thread_7_Mutator::instr_func(BPatch_function *func,
90                                        BPatch_function *lvl1func) {
91    BPatch_Vector<BPatch_point *> *points;
92    points = func->findPoint(BPatch_entry);
93    for (unsigned j=0; j < points->size(); j++)
94    {
95       BPatch_point *point = (*points)[j];
96       BPatch_Vector<BPatch_snippet *> args;
97       BPatch_funcCallExpr callToLevel1(*lvl1func, args);
98       BPatchSnippetHandle *hndl;
99       hndl = proc->insertSnippet(callToLevel1, *point, BPatch_firstSnippet);
100       // FIXME Don't think we want to assert here.  It's possible this call
101       // might fail for some reason, and we're better off returning a failure
102       // code then rather than just crashing the test driver
103       assert(hndl);
104    }
105 }
106
107 BPatch_process *test_thread_7_Mutator::getProcess() {
108   int n = 0;
109   args[n++] = filename;
110
111   args[n++] = "-run";
112   args[n++] = "test_thread_7";
113
114   // Set up log file!
115   args[n++] = "-log";
116   args[n++] = const_cast<char*>(getOutputLogFilename());
117
118   args[n] = NULL;
119
120    BPatch_process *proc = NULL;
121    if (create_proc) {
122       proc = bpatch->processCreate(filename, (const char **) args);
123       if(proc == NULL) {
124          logerror("%s[%d]: processCreate(%s) failed\n", 
125                  __FILE__, __LINE__, filename);
126          return NULL;
127       }
128       registerPID(proc->getPid()); // Register for cleanup
129    }
130    else
131    {
132       dprintf(stderr, "%s[%d]: starting process for attach\n", __FILE__, __LINE__);
133       int pid = startNewProcessForAttach(filename, (const char **) args,
134                                          getOutputLog(), getErrorLog(), true);
135       if (pid < 0) {
136          int errnum = errno;
137          errno = 0;
138          char *errstr = strerror(errnum);
139          logerror("%s couldn't be started: %s\n", filename,
140                   errno ? "<unknown error>" : errstr);
141          return NULL;
142       } else if (pid > 0) {
143         registerPID(pid); // Register for cleanup
144       }
145 #if defined(os_windows_test)
146       P_sleep(1);
147 #endif
148       dprintf(stderr, "%s[%d]: started process, now attaching\n", __FILE__, __LINE__);
149       proc = bpatch->processAttach(filename, pid);  
150       if(proc == NULL) {
151          logerror("%s[%d]: processAttach(%s, %d) failed\n", 
152                   __FILE__, __LINE__, filename, pid);
153          return NULL;
154       }
155       dprintf(stderr, "%s[%d]: attached to process\n", __FILE__, __LINE__);
156       BPatch_image *appimg = proc->getImage();
157       signalAttached(NULL, appimg);
158    }
159    return proc;
160 }
161
162 test_results_t test_thread_7_Mutator::executeTest() {
163   memset(args, 0, sizeof (args));
164
165    proc = getProcess();
166    if (!proc) {
167      return FAILED;
168    }
169
170    BPatch_image *image = proc->getImage();
171    BPatch_Vector<BPatch_function *> lvl1funcs;
172    image->findFunction("test_thread_7_level1", lvl1funcs);
173    if (lvl1funcs.size() != 1)
174    {
175       logerror("[%s:%u] - Found %d level1 functions.  Expected 1\n",
176               __FILE__, __LINE__, lvl1funcs.size());
177       return FAILED;
178    }
179    BPatch_function *lvl1func = lvl1funcs[0];
180
181    BPatch_Vector<BPatch_function *> funcs;
182    image->findFunction("test_thread_7_level0", funcs);
183    instr_func(funcs[0], lvl1func);
184    funcs.clear();
185    image->findFunction("test_thread_7_level1", funcs);
186    instr_func(funcs[0], lvl1func);
187    funcs.clear();
188    image->findFunction("test_thread_7_level2", funcs);
189    instr_func(funcs[0], lvl1func);
190    funcs.clear();
191    image->findFunction("test_thread_7_level3", funcs);
192    instr_func(funcs[0], lvl1func);
193    funcs.clear();
194
195    proc->continueExecution();
196
197    do {
198       bpatch->waitForStatusChange();
199    } while (!proc->isTerminated());
200
201    int exitCode = proc->getExitCode();
202    if (exitCode)
203    {
204        logstatus("*** Failed test_thread_7 (Multithreaded tramp guards)\n");
205        return FAILED;
206    }
207    else
208    {
209        logstatus("Passed test_thread_7 (Multithreaded tramp guards)\n");
210        logstatus("All tests passed.\n");
211    }
212    return PASSED;
213 }
214
215 //extern "C" TEST_DLL_EXPORT int test14_1_mutatorMAIN(ParameterDict &param)
216 test_results_t test_thread_7_Mutator::setup(ParameterDict &param) {
217    bpatch = (BPatch *)(param["bpatch"]->getPtr());
218    filename = param["pathname"]->getString();
219
220    if ( param["useAttach"]->getInt() != 0 )
221    {
222       create_proc = false;
223    }
224
225    return PASSED;
226 }