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