diff --git a/proctl/threads_darwin.c b/proctl/threads_darwin.c index cfe76d18..5e9b92f9 100644 --- a/proctl/threads_darwin.c +++ b/proctl/threads_darwin.c @@ -74,8 +74,22 @@ single_step(thread_act_t thread) { kret = thread_set_state(thread, x86_THREAD_STATE64, (thread_state_t)®s, count); if (kret != KERN_SUCCESS) return kret; - // Continue here until we've fully decremented suspend_count - for (;;) { + kret = resume_thread(thread); + if (kret != KERN_SUCCESS) return kret; + + return KERN_SUCCESS; +} + +kern_return_t +resume_thread(thread_act_t thread) { + kern_return_t kret; + struct thread_basic_info info; + unsigned int info_count = THREAD_BASIC_INFO_COUNT; + + kret = thread_info((thread_t)thread, THREAD_BASIC_INFO, (thread_info_t)&info, &info_count); + if (kret != KERN_SUCCESS) return kret; + + for (int i = 0; i < info.suspend_count; i++) { kret = thread_resume(thread); if (kret != KERN_SUCCESS) break; } diff --git a/proctl/threads_darwin.go b/proctl/threads_darwin.go index 14a3bf85..77333399 100644 --- a/proctl/threads_darwin.go +++ b/proctl/threads_darwin.go @@ -38,10 +38,9 @@ func (t *ThreadContext) resume() error { if PtraceCont(t.Process.Pid, 0) == nil { return nil } - for { - if C.thread_resume(t.os.thread_act) != C.KERN_SUCCESS { - break - } + kret := C.resume_thread(t.os.thread_act) + if kret != C.KERN_SUCCESS { + return fmt.Errorf("could not continue thread") } return nil } diff --git a/proctl/threads_darwin.h b/proctl/threads_darwin.h index 22f76cba..e03d6ce7 100644 --- a/proctl/threads_darwin.h +++ b/proctl/threads_darwin.h @@ -19,4 +19,7 @@ kern_return_t single_step(thread_act_t); kern_return_t -clear_trap_flag(thread_act_t thread); +clear_trap_flag(thread_act_t); + +kern_return_t +resume_thread(thread_act_t);