// static bool mutatorTest3and4(int testno, const char *testname) test_results_t test_thread_2_Mutator::executeTest() { test3_threadCreateCounter = 0; callback_tids.clear(); BPatchAsyncThreadEventCallback createcb = threadCreateCB; if (!bpatch->registerThreadEventCallback(BPatch_threadCreateEvent, createcb)) { FAIL_MES(TESTNAME, TESTDESC); logerror("%s[%d]: failed to register thread callback\n", __FILE__, __LINE__); appThread->getProcess()->terminateExecution(); return FAILED; } #if 0 // unset mutateeIde to trigger thread (10) spawn. int zero = 0; // FIXME Check the return code for setVar setVar("mutateeIdle", (void *) &zero, TESTNO, TESTDESC); dprintf("%s[%d]: continue execution for test %d\n", __FILE__, __LINE__, TESTNO); appThread->continueExecution(); #endif if( !appProc->continueExecution() ) { logerror("%s[%d]: failed to continue process\n", FILE__, __LINE__); appProc->terminateExecution(); return FAILED; } // wait until we have received the desired number of events int err = 0; BPatch_Vector<BPatch_thread *> threads; BPatch_process *appProc = appThread->getProcess(); assert(appProc); appProc->getThreads(threads); int active_threads = 11; // FIXME Magic number threads.clear(); while (((test3_threadCreateCounter < TEST3_THREADS) || (active_threads > 1)) && !appProc->isTerminated() ) { dprintf("%s[%d]: waiting for completion for test; ((%d < %d) || (%d > 1)) && !(%d)\n", __FILE__, __LINE__, test3_threadCreateCounter, TEST3_THREADS, active_threads, 1, appProc->isTerminated()); if( !bpatch->waitForStatusChange() ) { logerror("%s[%d]: failed to wait for events\n", __FILE__, __LINE__); err = 1; break; } appProc->getThreads(threads); active_threads = threads.size(); threads.clear(); } if( appProc->isTerminated() ) { logerror("%s[%d]: BAD NEWS: somehow the process died\n", __FILE__, __LINE__); return FAILED; } dprintf("%s[%d]: ending test %d, num active threads = %d\n", __FILE__, __LINE__, TESTNO, active_threads); dprintf("%s[%d]: stop execution for test %d\n", __FILE__, __LINE__, TESTNO); appProc->stopExecution(); // read all tids from the mutatee and verify that we got them all unsigned long mutatee_tids[TEST3_THREADS]; const char *threads_varname = "test3_threads"; if (getVar(threads_varname, (void *) mutatee_tids, (sizeof(unsigned long) * TEST3_THREADS), TESTNO, TESTDESC)) { appProc->terminateExecution(); return FAILED; } if (debugPrint()) { dprintf("%s[%d]: read following tids for test%d from mutatee\n", __FILE__, __LINE__, TESTNO); for (unsigned int i = 0; i < TEST3_THREADS; ++i) { dprintf("\t%lu\n", mutatee_tids[i]); } } for (unsigned int i = 0; i < TEST3_THREADS; ++i) { bool found = false; for (unsigned int j = 0; j < callback_tids.size(); ++j) { if (callback_tids[j] == mutatee_tids[i]) { found = true; break; } } if (!found) { FAIL_MES(TESTNAME, TESTDESC); logerror("%s[%d]: could not find record for tid %lu: have these:\n", __FILE__, __LINE__, mutatee_tids[i]); for (unsigned int j = 0; j < callback_tids.size(); ++j) { logerror("%lu\n", callback_tids[j]); } err = 1; break; } } dprintf("%s[%d]: removing thread callback\n", __FILE__, __LINE__); if (!bpatch->removeThreadEventCallback(BPatch_threadCreateEvent, createcb)) { FAIL_MES(TESTNAME, TESTDESC); logerror("%s[%d]: failed to remove thread callback\n", __FILE__, __LINE__); err = 1; } if (!err) { logerror("No error reported, terminating process and returning success\n"); PASS_MES(TESTNAME, TESTDESC); appProc->terminateExecution(); logerror("\t Process terminated\n"); return PASSED; } appProc->terminateExecution(); return FAILED; }
// static bool mutatorTest3and4(int testno, const char *testname) test_results_t test_thread_3_Mutator::executeTest() { test3_threadCreateCounter = 0; callback_tids.clear(); unsigned int timeout = 0; // in ms int err = 0; BPatchAsyncThreadEventCallback createcb = threadCreateCB; if (!bpatch->registerThreadEventCallback(BPatch_threadCreateEvent, createcb)) { FAIL_MES(TESTNAME, TESTDESC); logerror("%s[%d]: failed to register thread callback\n", __FILE__, __LINE__); appThread->getProcess()->terminateExecution(); return FAILED; } #if 0 // unset mutateeIde to trigger thread (10) spawn. int zero = 0; // FIXME Check the return value of setVar() setVar("mutateeIdle", (void *) &zero, TESTNO, TESTDESC); dprintf("%s[%d]: continue execution for test %d\n", __FILE__, __LINE__, TESTNO); appThread->continueExecution(); #endif // wait until we have received the desired number of events // (or timeout happens) BPatch_Vector<BPatch_thread *> threads; BPatch_process *appProc = appThread->getProcess(); assert(appProc); appProc->getThreads(threads); int active_threads = 11; // FIXME Magic number threads.clear(); while (((test3_threadCreateCounter < TEST3_THREADS) || (active_threads > 1)) && (timeout < TIMEOUT)) { dprintf("%s[%d]: waiting for completion for test %d, num active threads = %d\n", __FILE__, __LINE__, TESTNO, active_threads); sleep_ms(SLEEP_INTERVAL/*ms*/); timeout += SLEEP_INTERVAL; if (appProc->isTerminated()) { dprintf("%s[%d]: BAD NEWS: somehow the process died\n", __FILE__, __LINE__); err = 1; break; } bpatch->pollForStatusChange(); if (appProc->isStopped()) { appProc->continueExecution(); } appProc->getThreads(threads); active_threads = threads.size(); threads.clear(); } if (timeout >= TIMEOUT) { FAIL_MES(TESTNAME, TESTDESC); logerror("%s[%d]: test timed out. got %d/10 events\n", __FILE__, __LINE__, test3_threadCreateCounter); logerror("test3_createCounter is %d, expected %d; active threads %d, expected %d\n", test3_threadCreateCounter, TEST3_THREADS, active_threads, 1); err = 1; } dprintf("%s[%d]: ending test %d, num active threads = %d\n", __FILE__, __LINE__, TESTNO, active_threads); dprintf("%s[%d]: stop execution for test %d\n", __FILE__, __LINE__, TESTNO); appProc->stopExecution(); // read all tids from the mutatee and verify that we got them all unsigned long mutatee_tids[TEST3_THREADS]; const char *threads_varname = "test4_threads"; getVar(threads_varname, (void *) mutatee_tids, (sizeof(unsigned long) * TEST3_THREADS), TESTNO, TESTDESC); if (debugPrint()) { dprintf("%s[%d]: read following tids for test%d from mutatee\n", __FILE__, __LINE__, TESTNO); for (unsigned int i = 0; i < TEST3_THREADS; ++i) { dprintf("\t%lu\n", mutatee_tids[i]); } } for (unsigned int i = 0; i < TEST3_THREADS; ++i) { bool found = false; for (unsigned int j = 0; j < callback_tids.size(); ++j) { if (callback_tids[j] == mutatee_tids[i]) { found = true; break; } } if (!found) { FAIL_MES(TESTNAME, TESTDESC); logerror("%s[%d]: could not find record for tid %lu: have these:\n", __FILE__, __LINE__, mutatee_tids[i]); for (unsigned int j = 0; j < callback_tids.size(); ++j) { logerror("%lu\n", callback_tids[j]); } err = true; break; } } dprintf("%s[%d]: removing thread callback\n", __FILE__, __LINE__); if (!bpatch->removeThreadEventCallback(BPatch_threadCreateEvent, createcb)) { FAIL_MES(TESTNAME, TESTDESC); logerror("%s[%d]: failed to remove thread callback\n", __FILE__, __LINE__); err = true; } if (!err) { PASS_MES(TESTNAME, TESTDESC); appProc->terminateExecution(); return PASSED; } appProc->terminateExecution(); return FAILED; }