Update copyright to LGPL on all files
[dyninst.git] / testsuite / src / dyninst / test_callback_1.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 // $Id: test_callback_1.C,v 1.1 2008/10/30 19:21:24 legendre Exp $
33 /*
34  * #Name: test12_2
35  * #Desc: dynamic callsite callback
36  * #Dep: 
37  * #Arch: !(os_windows,os_irix)
38  * #Notes:
39  */
40
41 #include "BPatch.h"
42 #include "BPatch_Vector.h"
43 #include "BPatch_thread.h"
44 #include "BPatch_snippet.h"
45
46 #include "test_lib.h"
47 #include "test12.h"
48
49 #include "dyninst_comp.h"
50 class test_callback_1_Mutator : public DyninstMutator {
51 protected:
52   BPatch *bpatch;
53
54 public:
55   virtual bool hasCustomExecutionPath() { return true; }
56   virtual test_results_t setup(ParameterDict &param);
57   virtual test_results_t executeTest();
58 };
59 extern "C" DLLEXPORT TestMutator *test_callback_1_factory() {
60   return new test_callback_1_Mutator();
61 }
62
63 #define TESTNO 2
64 #define TESTNAME "test_callback_1"
65 #define TESTDESC "dynamic callsite callback"
66
67 static const char *expected_fnames[] = {"call2_1","call2_2","call2_3","call2_4"};
68 static int test2done = 0;
69 static int test2err = 0;
70 static int mutateeXLC = 0;
71 static int debugPrint;
72 template class BPatch_Vector<void *>;
73 static BPatch_Vector<BPatch_point *> test2handles;
74 static BPatch_Vector<BPatch_point *> dyncalls;
75 static BPatch_thread *globalThread = NULL;
76 extern BPatch *bpatch;
77   static int counter = 0;
78   static int counter2 = 0;
79
80 static void dynSiteCB(BPatch_point *dyn_site, BPatch_function *called_function)
81 {
82   //dprintf("%s[%d]:  dynSiteCB: pt = %p. func = %p.\n",
83   //                 __FILE__, __LINE__, dyn_site, called_function);
84   //  static int counter = 0;
85   //  static int counter2 = 0;
86   BPatch_point *pt = dyn_site;
87   BPatch_function *func = called_function;
88   assert(pt);
89   assert(func);
90
91   void *callsite_addr = pt->getAddress();
92   dprintf("%s[%d]:  callsite addr = %p\n", __FILE__, __LINE__, callsite_addr);
93
94   char buf[2048];
95   func->getName(buf, 2048);
96   //dprintf("%s[%d]:  got func %s, expect func %s\n", __FILE__, __LINE__, buf,
97   //        expected_fnames[counter]);
98   if (strcmp(expected_fnames[counter], buf)) {
99     FAIL_MES(TESTNAME, TESTDESC);
100     dprintf("\t%s[%d]:  got func %s, expect func %s\n", __FILE__, __LINE__, buf,
101           expected_fnames[counter]);
102     globalThread->stopExecution();
103     test2done = 1;
104   }
105   counter++;
106   if (counter > 3) {
107     counter = 0;
108     counter2++;
109   }
110
111   if (counter2 >= 2) {
112     bool removal_error = false;
113     globalThread->stopExecution();
114     //  not passed yet, now remove dynamic call monitoring handles
115     assert (test2handles.size());
116     for (unsigned int i = 0; i < test2handles.size(); ++i) {
117       if (!test2handles[i]->stopMonitoring()) {
118         removal_error = true;
119       }
120     }
121     if (removal_error) {
122       FAIL_MES("test_callback_1", TESTDESC);
123       test2err = 1;
124     }else {
125       PASS_MES("test_callback_1", TESTDESC);
126     }
127     test2done = 1;
128   }
129 }
130
131
132 // static int mutatorTest(BPatch_thread *appThread, BPatch_image *appImage)
133 test_results_t test_callback_1_Mutator::executeTest() {
134   dprintf("%s[%d]:  welcome to test12_2\n", __FILE__, __LINE__);
135   int timeout = 0;
136   globalThread = appThread;
137   test2done = 0;
138   test2err = 0;
139   dyncalls.clear();
140   test2handles.clear();
141   counter = 0;
142   counter2 = 0;
143
144   if (mutateeXLC) {
145     // Why are we continuing the mutatee?  Doesn't it just start looping
146     // forever when we do this?
147     //appThread->continueExecution();
148      appThread->terminateExecution();
149      SKIP(TESTNAME, TESTDESC);
150      logerror("\txlc optimizes out dynamic call sites for this test\n");
151      sleep_ms(100);
152      return SKIPPED;
153   }
154
155   if (!bpatch->registerDynamicCallCallback(dynSiteCB)) {
156      FAIL_MES(TESTNAME, TESTDESC);
157      logerror("  failed to register callsite callback\n");
158      appThread->terminateExecution();
159      return FAILED;
160   }
161
162   BPatch_function *func2_1 = findFunction("call2_dispatch", appThread->getImage(), TESTNO, TESTNAME);
163   BPatch_function *targetFunc = func2_1;
164
165   BPatch_Vector<BPatch_point *> *calls = targetFunc->findPoint(BPatch_subroutine);
166   if (!calls) {
167      FAIL_MES(TESTNAME, TESTDESC);
168      logerror("  cannot find call points for func1_1\n");
169      appThread->terminateExecution();
170      return FAILED;
171   }
172
173   for (unsigned int i = 0; i < calls->size(); ++i) {
174     BPatch_point *pt = (*calls)[i];
175     if (pt->isDynamic()){
176       bool ret;
177       ret = pt->monitorCalls();
178       if (!ret) {
179         FAIL_MES(TESTNAME, TESTDESC);
180         logerror("  failed monitorCalls\n");
181         appThread->terminateExecution();
182         return FAILED;
183       }
184       test2handles.push_back(pt);
185       dyncalls.push_back(pt);
186     }
187   }
188
189   if (dyncalls.size() != 3) {
190      FAIL_MES(TESTNAME, TESTDESC);
191      logerror("  wrong number of dynamic points found (%d -- not 3)\n",
192              dyncalls.size());
193      logerror("  total number of calls found: %d\n", calls->size());
194      appThread->terminateExecution();
195      return FAILED;
196   }
197
198   appThread->continueExecution();
199
200   //  wait until we have received the desired number of events
201   //  (or timeout happens)
202
203   while(!test2done && (timeout < TIMEOUT)) {
204     bpatch->pollForStatusChange();
205     sleep_ms(SLEEP_INTERVAL/*ms*/);
206     timeout += SLEEP_INTERVAL;
207   }
208
209   if (timeout >= TIMEOUT) {
210     FAIL_MES(TESTNAME, TESTDESC);
211     logerror("%s[%d]:  test timed out.\n",
212            __FILE__, __LINE__);
213     test2err = 1;
214   }
215
216   if (test2err) {
217     appThread->terminateExecution();
218     return FAILED;
219   } else {
220     appThread->terminateExecution();
221     return PASSED;
222   }
223 }
224
225 //extern "C" int test12_2_mutatorMAIN(ParameterDict &param)
226 test_results_t test_callback_1_Mutator::setup(ParameterDict &param) {
227 #ifdef os_windows_test
228   return SKIPPED;
229 #else
230     bpatch = (BPatch *)(param["bpatch"]->getPtr());
231     debugPrint = param["debugPrint"]->getInt();
232     mutateeXLC = param["mutateeXLC"]->getInt();
233
234     if (DyninstMutator::setup(param) == FAILED) {
235       return FAILED;
236     }
237     
238     // TODO Move the sanity check block below into executeTest()
239
240     //  sanity checks?? -- should not be necesssary, but if they're not mentioned here, they aren't always found
241     //  later, suggests issue with delayed parsing?
242     BPatch_function *f;
243     if (NULL == (f = findFunction("call2_1", appImage, TESTNO, TESTNAME)))
244       return FAILED;
245     if (NULL == (f = findFunction("call2_2", appImage, TESTNO, TESTNAME)))
246       return FAILED;
247     if (NULL == (f = findFunction("call2_3", appImage, TESTNO, TESTNAME)))
248       return FAILED;
249     if (NULL == (f = findFunction("call2_4", appImage, TESTNO, TESTNAME)))
250       return FAILED;
251
252     return PASSED;
253 #endif // Not Windows
254 }