Ejemplo n.º 1
0
ErrorCode Thread::step(int signal, Address const &address) {
  // Windows doesn't have a dedicated single-step call. We have to set the
  // single step flag (TF, 8th bit) in eflags and resume the thread.
  ErrorCode error = modifyRegisters(
      [](Architecture::CPUState &state) { state.gp.eflags |= (1 << 8); });
  if (error != kSuccess) {
    return error;
  }
  return resume(signal, address);
}
Ejemplo n.º 2
0
ErrorCode Thread::resume(int signal, Address const &address) {
  // TODO(sas): Not sure how to translate the signal concept to Windows yet.
  // We'll probably have to get rid of these at some point.
  DS2ASSERT(signal == 0);

  if (address.valid()) {
    CHK(modifyRegisters(
        [&address](Architecture::CPUState &state) { state.setPC(address); }));
  }

  switch (_state) {
  case kInvalid:
  case kRunning:
    DS2BUG("trying to suspend tid %" PRI_PID " in state %s", tid(),
           Stringify::ThreadState(_state));
    break;

  case kTerminated:
    return kErrorProcessNotFound;

  case kStopped:
  case kStepped: {
    if (_stopInfo.event == StopInfo::kEventStop &&
        _stopInfo.reason == StopInfo::kReasonNone) {
      DWORD result = ::ResumeThread(_handle);
      if (result == (DWORD)-1) {
        return Platform::TranslateError();
      }
    } else {
      BOOL result = ::ContinueDebugEvent(_process->pid(), _tid, DBG_CONTINUE);
      if (!result) {
        return Platform::TranslateError();
      }
    }

    _state = kRunning;
    return kSuccess;
  }
  }

  // Silence warnings without using a `default:` case for the above switch.
  DS2_UNREACHABLE();
}