debugserver per-thread suspension and resume preparation
Per-thread suspend-count accounting and the callbacks that prepare register and architecture state before resume and normalize it after a stop.
MachThread::Suspend source
void MachThread::Suspend() {
DNBLogThreadedIf(LOG_THREAD | LOG_VERBOSE, "MachThread::%s ( )",
__FUNCTION__);
if (MachPortNumberIsValid(m_mach_port_number)) {
DNBError err(::thread_suspend(m_mach_port_number), DNBError::MachKernel);
if (err.Success())
m_suspend_count++;
if (DNBLogCheckLogBit(LOG_THREAD) || err.Fail())
err.LogThreaded("::thread_suspend (%4.4" PRIx32 ")", m_mach_port_number);
}
}MachThread::Resume source
void MachThread::Resume(bool others_stopped) {
DNBLogThreadedIf(LOG_THREAD | LOG_VERBOSE, "MachThread::%s ( )",
__FUNCTION__);
if (MachPortNumberIsValid(m_mach_port_number)) {
SetSuspendCountBeforeResume(others_stopped);
}
}MachThread::ThreadWillResume source
void MachThread::ThreadWillResume(const DNBThreadResumeAction *thread_action,
bool others_stopped) {
if (thread_action->addr != INVALID_NUB_ADDRESS)
SetPC(thread_action->addr);
SetState(thread_action->state);
switch (thread_action->state) {
case eStateStopped:
case eStateSuspended:
assert(others_stopped == false);
Suspend();
break;
case eStateRunning:
case eStateStepping:
Resume(others_stopped);
break;
default:
break;
}
m_arch_up->ThreadWillResume();
m_stop_exception.Clear();
}MachThread::ThreadDidStop source
bool MachThread::ThreadDidStop() {
// This thread has existed prior to resuming under debug nub control,
// and has just been stopped. Do any cleanup that needs to be done
// after running.
// The thread state and breakpoint will still have the same values
// as they had prior to resuming the thread, so it makes it easy to check
// if we were trying to step a thread, or we tried to resume while being
// at a breakpoint.
// When this method gets called, the process state is still in the
// state it was in while running so we can act accordingly.
m_arch_up->ThreadDidStop();
// We may have suspended this thread so the primary thread could step
// without worrying about race conditions, so lets restore our suspend
// count.
RestoreSuspendCountAfterStop();
// Update the basic information for a thread
MachThread::GetBasicInfo(m_mach_port_number, &m_basic_info);
if (m_basic_info.suspend_count > 0)
SetState(eStateSuspended);
else
SetState(eStateStopped);
return true;
}