ErrorCode ProcessBase::resume(int signal, std::set<Thread *> const &excluded) { enumerateThreads([&](Thread *thread) { if (excluded.find(thread) != excluded.end()) return; switch (thread->state()) { case Thread::kInvalid: case Thread::kTerminated: DS2BUG("trying to resume tid %" PRI_PID " in state %s", thread->tid(), Stringify::ThreadState(thread->state())); break; case Thread::kRunning: DS2LOG(Debug, "not resuming tid %" PRI_PID ", already in state %s", thread->tid(), Stringify::ThreadState(thread->state())); break; case Thread::kStopped: case Thread::kStepped: { Architecture::CPUState state; thread->readCPUState(state); DS2LOG(Debug, "resuming tid %" PRI_PID " from pc %" PRI_PTR " with signal %d", thread->tid(), PRI_PTR_CAST(state.pc()), signal); ErrorCode error = thread->resume(signal); if (error != kSuccess) { DS2LOG(Warning, "failed resuming tid %" PRI_PID ", error=%s", thread->tid(), Stringify::Error(error)); } } break; } }); return kSuccess; }
ErrorCode ProcessBase::suspend() { std::set<Thread *> threads; enumerateThreads([&](Thread *thread) { threads.insert(thread); }); for (auto thread : threads) { switch (thread->state()) { case Thread::kInvalid: DS2BUG("trying to suspend tid %" PRI_PID " in state %s", thread->tid(), Stringify::ThreadState(thread->state())); break; case Thread::kStepped: case Thread::kStopped: case Thread::kTerminated: DS2LOG(Debug, "not suspending tid %" PRI_PID ", already in state %s", thread->tid(), Stringify::ThreadState(thread->state())); if (thread->state() == Thread::kTerminated) { removeThread(thread->tid()); } break; case Thread::kRunning: { DS2LOG(Debug, "suspending tid %" PRI_PID, thread->tid()); ErrorCode error = thread->suspend(); switch (error) { case kSuccess: break; case kErrorProcessNotFound: DS2LOG(Debug, "tried to suspended tid %" PRI_PID " which is already dead", thread->tid()); removeThread(thread->tid()); return error; default: DS2LOG(Warning, "failed suspending tid %" PRI_PID ", error=%s", thread->tid(), Stringify::Error(error)); return error; } } break; } } return kSuccess; }
ErrorCode Process::suspend() { std::set<Thread *> threads; enumerateThreads([&](Thread *thread) { threads.insert(thread); }); for (auto thread : threads) { Architecture::CPUState state; if (thread->state() != Thread::kRunning) { thread->readCPUState(state); } DS2LOG(Debug, "tid %d state %d at pc %#" PRIx64, thread->tid(), thread->state(), thread->state() == Thread::kStopped ? (uint64_t)state.pc() : 0); if (thread->state() == Thread::kRunning) { ErrorCode error; DS2LOG(Debug, "suspending tid %d", thread->tid()); error = thread->suspend(); if (error == kSuccess) { DS2LOG(Debug, "suspended tid %d at pc %#" PRIx64, thread->tid(), (uint64_t)state.pc()); thread->readCPUState(state); } else if (error == kErrorProcessNotFound) { // // Thread is dead. // removeThread(thread->tid()); DS2LOG(Debug, "tried to suspended tid %d which is already dead", thread->tid()); } else { return error; } } else if (thread->state() == Thread::kTerminated) { // // Thread is dead. // removeThread(thread->tid()); } } return kSuccess; }
ErrorCode Process::resume(int signal, std::set<Thread *> const &excluded) { enumerateThreads([&](Thread *thread) { if (excluded.find(thread) != excluded.end()) return; if (thread->state() == Thread::kStopped || thread->state() == Thread::kStepped) { Architecture::CPUState state; thread->readCPUState(state); DS2LOG(Debug, "resuming tid %I64u from pc %#I64x", (uint64_t)thread->tid(), (uint64_t)state.pc()); ErrorCode error = thread->resume(signal); if (error != kSuccess) { DS2LOG(Warning, "failed resuming tid %I64u, error=%d", (uint64_t)thread->tid(), error); } } }); return kSuccess; }