Exemple #1
0
Dispatcher::~Dispatcher() {
	auto locked = _mutex.try_lock();
	if (!locked) {
		LOGe("Dispatcher deleted while in use.");
		assert(locked);

		_mutex.lock();
	}

	if (_state != State::STOPPED) {
		LOGe("Dispatcher deleted but not yet stopped. Forgot to call waitUntilStopped()?");
		assert(_state == State::STOPPED);

		if (std::this_thread::get_id() != _thread.get_id()) {
			if (_state == State::STARTED) {
				stop();
			}

			waitUntilStopped();
		}
		else {
			LOGe("Cannot delete the dispatcher from within the dispatcher thread.");
		}
	}

	_mutex.unlock();
}
Exemple #2
0
// static int mutatorTest(BPatch_thread *appThread, BPatch_image *appImage)
test_results_t test_stack_1_Mutator::executeTest() {
    appProc->continueExecution();
    static const frameInfo_t correct_frame_info[] = {
#if defined( os_linux_test ) && (defined( arch_x86_test ) || defined( arch_x86_64_test ))
	{ true, true, BPatch_frameNormal, "_dl_sysinfo_int80" },
#endif
#if !defined(rs6000_ibm_aix4_1_test)
	{ false, false, BPatch_frameNormal, NULL },
#endif
#if !defined(i386_unknown_nt4_0_test)
	{ true,  false, BPatch_frameNormal, "stop_process_" },
#endif
	{ true,  false, BPatch_frameNormal, "test_stack_1_func3" },
	{ true,  false, BPatch_frameNormal, "test_stack_1_func2" },
	{ true,  false, BPatch_frameNormal, "test_stack_1_func1" },
	{ true,  false, BPatch_frameNormal, "test_stack_1_mutateeTest" },
	{ true,  false, BPatch_frameNormal, "main" },
    };

    if (waitUntilStopped(bpatch, appProc, 1, "getCallStack") < 0) {
      appProc->terminateExecution();
      return FAILED;
    }

    if (checkStack(appThread,
		   correct_frame_info,
		   sizeof(correct_frame_info)/sizeof(frameInfo_t),
		   1, "getCallStack")) {
	logerror("Passed test #1 (getCallStack)\n");

    } else {
      appProc->terminateExecution();
       return FAILED;
    }

    appProc->continueExecution();
    while (!appProc->isTerminated()) {
      bpatch->waitForStatusChange();
    }

    return PASSED;
}
Exemple #3
0
// static int mutatorTest( BPatch_thread * appThread, BPatch_image * appImage ) {
test_results_t test_stack_3_Mutator::executeTest() {
  bool passedTest;

  BPatch::bpatch->setInstrStackFrames(true);
  appProc->continueExecution();
  static const frameInfo_t correct_frame_info[] = {
	
#if defined( os_linux_test ) && (defined( arch_x86_test ) || defined( arch_x86_64_test ))
    { true, true, BPatch_frameNormal, "_dl_sysinfo_int80" },
#endif
#if defined( os_aix_test ) && defined( arch_power_test )
    /* AIX uses kill(), but the PC of a process in a syscall can
       not be correctly determined, and appears to be the address
       to which the syscall function will return. */
#elif defined( os_windows_test ) && (defined( arch_x86 ) || defined( arch_x86_64_test ))
    /* Windows/x86 does not use kill(), so its lowermost frame will be 
       something unidentifiable in a system DLL. */
    { false, false, BPatch_frameNormal, NULL },
#else
    { true, false, BPatch_frameNormal, "kill" },	
#endif
#if ! defined( os_windows_test )
    /* Windows/x86's stop_process_() calls DebugBreak(); it's 
       apparently normal to lose this frame. */
    { true, false, BPatch_frameNormal, "stop_process_" },
#endif
    { true, false, BPatch_frameNormal, "test_stack_3_func3" },
    { true, false, BPatch_frameTrampoline, NULL },
    /* On AIX and x86 (and others), if our instrumentation fires
       before frame construction or after frame destruction, it's 
       acceptable to not report the function (since, after all, it
       doesn't have a frame on the stack. */
    { true, true, BPatch_frameNormal, "test_stack_3_func2" },
    { true, false, BPatch_frameNormal, "test_stack_3_func1" },
    { true, false, BPatch_frameNormal, "test_stack_3_mutateeTest" },
    { true, false, BPatch_frameNormal, "main" }
  };
	
  /* Wait for the mutatee to stop in test_stack_3_func1(). */
  if (waitUntilStopped( bpatch, appProc, 1, "getCallStack through instrumentation") < 0) {
      appProc->terminateExecution();
    return FAILED;
  }
	
  /* Instrument test_stack_3_func2() to call test_stack_3_func3(), which will trip another breakpoint. */
  BPatch_Vector<BPatch_function *> instrumentedFunctions;	
  const char *fName = "test_stack_3_func2";
  appImage->findFunction(fName, instrumentedFunctions );
  if (instrumentedFunctions.size() != 1) {
    // FIXME Print out a useful error message
    logerror("**Failed** test_stack_3\n");
    logerror("    Unable to find function '%s'\n", fName);
    appProc->terminateExecution();
    return FAILED;
  }
	
  BPatch_Vector<BPatch_point *> * functionEntryPoints = instrumentedFunctions[0]->findPoint( BPatch_entry );
  if (functionEntryPoints->size() != 1) {
    // FIXME Print out a useful error message
    logerror("**Failed** test_stack_3\n");
    logerror("    Unable to find entry point to function '%s'\n", fName);
    appProc->terminateExecution();
    return FAILED;
  }
	
  BPatch_Vector<BPatch_function *> calledFunctions;
  const char *fName2 = "test_stack_3_func3";
  appImage->findFunction(fName2, calledFunctions );
  if (calledFunctions.size() != 1) {
    //FIXME Print out a useful error message
    logerror("**Failed** test_stack_3\n");
    logerror("    Unable to find function '%s'\n", fName2);
    appProc->terminateExecution();
    return FAILED;
  }
	
  BPatch_Vector<BPatch_snippet *> functionArguments;
  BPatch_funcCallExpr functionCall( * calledFunctions[0], functionArguments );
	
  appProc->insertSnippet( functionCall, functionEntryPoints[0] );

  /* Repeat for all three types of instpoints. */
  BPatch_Vector<BPatch_point *> * functionCallPoints = instrumentedFunctions[0]->findPoint( BPatch_subroutine );
  if (functionCallPoints->size() != 1) {
    logerror("**Failed** test_stack_3\n");
    logerror("    Unable to find subroutine call points in '%s'\n", fName);
    appProc->terminateExecution();
    return FAILED;
  }
  appProc->insertSnippet( functionCall, functionCallPoints[0] );
	
  BPatch_Vector<BPatch_point *> * functionExitPoints = instrumentedFunctions[0]->findPoint( BPatch_exit );
  if (functionExitPoints->size() != 1) {
    logerror("**Failed** test_stack_3\n");
    logerror("    Unable to find exit points in '%s'\n", fName);
    appProc->terminateExecution();
    return FAILED;
  }
  appProc->insertSnippet( functionCall, functionExitPoints[0] );

#if defined( DEBUG )
  for( int i = 0; i < 80; i++ ) { ptrace( PTRACE_SINGLESTEP, appThread->getPid(), NULL, NULL ); }
	
  for( int i = 80; i < 120; i++ ) {
    ptrace( PTRACE_SINGLESTEP, appThread->getPid(), NULL, NULL );
		
    BPatch_Vector<BPatch_frame> stack;
    appThread->getCallStack( stack );
		
    dprintf("single-step stack walk, %d instructions after stop for instrumentation.\n", i );
    for( unsigned i = 0; i < stack.size(); i++ ) {
      char name[ 40 ];
      BPatch_function * func = stack[i].findFunction();
		
      if( func == NULL ) { strcpy( name, "[UNKNOWN]" ); }
      else { func->getName( name, 40 ); }
			
      dprintf("  %10p: %s, fp = %p\n", stack[i].getPC(), name, stack[i].getFP() );
    } /* end stack walk dumper */
    dprintf("end of stack walk.\n" );
  } /* end single-step iterator */
#endif /* defined( DEBUG ) */		

  /* After inserting the instrumentation, let it be called. */
  appProc->continueExecution();
	  
  /* Wait for the mutatee to stop because of the instrumentation we just inserted. */
  if (waitUntilStopped( bpatch, appProc, 1, "getCallStack through instrumentation (entry)") < 0) {
      appProc->terminateExecution();
    return FAILED;
  }

  passedTest = true;
  if( !checkStack( appThread, correct_frame_info,
		   sizeof(correct_frame_info)/sizeof(frameInfo_t),
		   3, "getCallStack through instrumentation (entry)" ) ) {
    passedTest = false;
  }

  /* Repeat for other two types of instpoints. */
  appProc->continueExecution();

  /* Wait for the mutatee to stop because of the instrumentation we just inserted. */
  if (waitUntilStopped( bpatch, appProc, 1, "getCallStack through instrumentation (call)") < 0) {
      appProc->terminateExecution();
    return FAILED;
  }

  if( !checkStack( appThread, correct_frame_info,
		   sizeof(correct_frame_info)/sizeof(frameInfo_t),
		   3, "getCallStack through instrumentation (call)" ) ) {
    passedTest = false;
  }
    	
  appProc->continueExecution();

  /* Wait for the mutatee to stop because of the instrumentation we just inserted. */
  if (waitUntilStopped( bpatch, appProc, 1, "getCallStack through instrumentation (exit)") < 0) {
      appProc->terminateExecution();
    return FAILED;
  }

  if( !checkStack( appThread, correct_frame_info,
		   sizeof(correct_frame_info)/sizeof(frameInfo_t),
		   3, "getCallStack through instrumentation (exit)" ) ) {
    passedTest = false;
  }

  if (passedTest)
    logerror("Passed test #3 (unwind through base and mini tramps)\n");

  /* Return the mutatee to its normal state. */
  appProc->continueExecution();

  while (!appProc->isTerminated()) {
    // Workaround for issue with pgCC_high mutatee
    bpatch->waitForStatusChange();
  }

  if (passedTest)
    return PASSED;
  return FAILED;
} /* end mutatorTest3() */
Exemple #4
0
test_results_t test1_19_Mutator::executeTest() 
{
    // Avoid a race condition in fast & loose mode

    while (!appProc->isStopped())
	{
		BPatch::bpatch->waitForStatusChange();
    }

    appProc->continueExecution();

    if (waitUntilStopped(BPatch::bpatch, appProc, 19, "oneTimeCode") < 0)
	{
      return FAILED;
    }

    BPatch_Vector<BPatch_function *> bpfv;
    const char *fn = "test1_19_call1";

    if (NULL == appImage->findFunction(fn, bpfv) || !bpfv.size()
	|| NULL == bpfv[0])
	{
      logerror("    Unable to find function %s\n", fn);
      return FAILED;
    }

    BPatch_function *call19_1_func = bpfv[0];

    BPatch_Vector<BPatch_snippet *> nullArgs;
    BPatch_funcCallExpr call19_1Expr(*call19_1_func, nullArgs);
    checkCost(call19_1Expr);

    appProc->oneTimeCode(call19_1Expr);

    // Let the mutatee run to check the result
    appProc->continueExecution();

    // Wait for the next test

    if (waitUntilStopped(BPatch::bpatch, appProc, 19, "oneTimeCode") < 0)
	{
      return FAILED;
    }

    bpfv.clear();
    const char *fn2 = "test1_19_call2";

    if (NULL == appImage->findFunction(fn2, bpfv) || !bpfv.size()
	|| NULL == bpfv[0])
	{
      logerror("    Unable to find function %s\n", fn2);
      return FAILED;
    }

    BPatch_function *call19_2_func = bpfv[0];

    BPatch_funcCallExpr call19_2Expr(*call19_2_func, nullArgs);
    checkCost(call19_2Expr);

    int callbackFlag = 0;

    // Register a callback that will set the flag callbackFlag
    BPatchOneTimeCodeCallback oldCallback = 
       BPatch::bpatch->registerOneTimeCodeCallback(test19_oneTimeCodeCallback);

    appProc->oneTimeCodeAsync(call19_2Expr, (void *)&callbackFlag);

    while (!appProc->isTerminated() && !appProc->isStopped() )
    {
		BPatch::bpatch->waitForStatusChange();
    }
    
    // Continue mutatee after one-time code runs
    appProc->continueExecution();

    // Wait for the callback to be called
    while (!appProc->isTerminated() && !callbackFlag) {
        if( !BPatch::bpatch->waitForStatusChange() ) {
            logerror("   FAILED: could not wait for callback to be called\n");
            return FAILED;
        }
    }

    if( !callbackFlag ) {
        logerror("     FAILED: process %d terminated while waiting for async oneTimeCode\n",
                appProc->getPid());
        return FAILED;
    }

    // After the oneTimeCode is completed, there could be a crash due to bugs in
    // the RPC code, wait for termination
    while( !appProc->isTerminated() ) {
        if( !BPatch::bpatch->waitForStatusChange() ) {
            logerror("   FAILED: could not wait for process to terminate\n");
            return FAILED;
        }
    }

    // Restore old callback (if there was one)
	BPatch::bpatch->registerOneTimeCodeCallback(oldCallback);

    return PASSED;
} // test1_19_Mutator::executeTest()