From 11405314d89aef7e09031d9c113b8ac3f48e341a Mon Sep 17 00:00:00 2001 From: Derek Parker Date: Sat, 7 Mar 2015 18:21:10 -0600 Subject: [PATCH] Continue thread properly taking into account suspend_count --- proctl/threads_darwin.c | 18 ++++++++++++++++-- proctl/threads_darwin.go | 7 +++---- proctl/threads_darwin.h | 5 ++++- 3 files changed, 23 insertions(+), 7 deletions(-) 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);