Commit 17e97322 authored by Cherry Zhang's avatar Cherry Zhang

runtime: overwrite asyncPreempt PC when injecting sigpanic on Windows

On Windows, it might be possible that SuspendThread suspends a
thread right between when an exception happens and when the
exception handler runs. (This is my guess. I don't know the
implementation detail of Windows exceptions to be sure.) In this
case, we may inject a call to asyncPreempt before the exception
handler runs. The exception handler will inject a sigpanic call,
which will make the stack trace looks like

sigpanic
asyncPreempt
actual panicking function

i.e. it appears asyncPreempt panicked.

Instead, just overwrite the PC, without pushing another frame.

Fixes #35773.

Change-Id: Ief4e964dcb7f45670b5f93c4dcf285cc1c737514
Reviewed-on: https://go-review.googlesource.com/c/go/+/213879
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarAustin Clements <austin@google.com>
parent 817afe83
......@@ -129,7 +129,14 @@ func exceptionhandler(info *exceptionrecord, r *context, gp *g) int32 {
// make the trace look like a call to runtime·sigpanic instead.
// (Otherwise the trace will end at runtime·sigpanic and we
// won't get to see who faulted.)
if r.ip() != 0 {
// Also don't push a sigpanic frame if the faulting PC
// is the entry of asyncPreempt. In this case, we suspended
// the thread right between the fault and the exception handler
// starting to run, and we have pushed an asyncPreempt call.
// The exception is not from asyncPreempt, so not to push a
// sigpanic call to make it look like that. Instead, just
// overwrite the PC. (See issue #35773)
if r.ip() != 0 && r.ip() != funcPC(asyncPreempt) {
sp := unsafe.Pointer(r.sp())
sp = add(sp, ^(unsafe.Sizeof(uintptr(0)) - 1)) // sp--
r.set_sp(uintptr(sp))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment