From 23d4b910c0328eaa4968e42f7d0f0df9ef08d3bc Mon Sep 17 00:00:00 2001 From: aarzilli Date: Fri, 10 Jan 2020 14:23:55 +0100 Subject: [PATCH] proc/native: partial support for Windows async preempt mechanism See https://github.com/golang/go/issues/36494 for a description of why full support for 1.14 under windows is problematic. --- pkg/proc/native/threads_windows.go | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/pkg/proc/native/threads_windows.go b/pkg/proc/native/threads_windows.go index 899962ba50..2d465f8eaf 100644 --- a/pkg/proc/native/threads_windows.go +++ b/pkg/proc/native/threads_windows.go @@ -36,9 +36,22 @@ func (t *Thread) singleStep() error { return err } - _, err = _ResumeThread(t.os.hThread) - if err != nil { - return err + suspendcnt := 0 + + // If a thread simultaneously hits a breakpoint and is suspended by the Go + // runtime it will have a suspend count greater than 1 and to actually take + // a single step we have to resume it multiple times here. + // We keep a counter of how many times it was suspended so that after + // single-stepping we can re-suspend it the corrent number of times. + for { + n, err := _ResumeThread(t.os.hThread) + if err != nil { + return err + } + suspendcnt++ + if n == 1 { + break + } } for { @@ -63,9 +76,11 @@ func (t *Thread) singleStep() error { }) } - _, err = _SuspendThread(t.os.hThread) - if err != nil { - return err + for i := 0; i < suspendcnt; i++ { + _, err = _SuspendThread(t.os.hThread) + if err != nil { + return err + } } t.dbp.execPtraceFunc(func() {