Description
If I understand correctly asynchronous preemption is implemented in Windows by:
- Calling SuspendThread on the target thread
- Waiting for SuspendThread to take effect by calling GetThreadContext
- Injecting a function call on the target thread by manipulating the context and calling SetThreadContext
- Calling ResumeThread on the target thread
This procedure being implemented by preemptM in src/runtime/os_windows.go.
However, from what I can observe, it seems that GetThreadContext will also return when the target thread get suspended after hitting a software breakpoint (placed by a debugger). This has two effects: first the breakpoint will be missed (because preemptM will manipulate the thread context to insert a function call, masking the breakpoint), secondly the return address for the injected call will be in the middle of an instruction (because the software breakpoint was partially overwriting an instruction).
A debugger that knows about this can work around it by checking if a thread is stopped on the entry point of asyncPreempt, and fix its return address. For this to work however preemptM needs to fully finish its context manipulation, if it ends up being stopped between the point where GetThreadContext returns and SetThreadContext is called the same problem will happen.
I'm not sure that there is a way to use software breakpoints with Go 1.14 with async preemption, as it currently is. Did I misunderstand anything?
Metadata
Metadata
Assignees
Labels
Type
Projects
Status