]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: crash earlier on windows for runtime.abort
authorRuss Cox <rsc@golang.org>
Wed, 27 Jan 2021 16:15:33 +0000 (11:15 -0500)
committerRuss Cox <rsc@golang.org>
Fri, 19 Feb 2021 00:03:52 +0000 (00:03 +0000)
The isAbort check was wrong for non-x86 systems.
That was causing the exception chain to be passed back to Windows.
That was causing some other kind of fault - not sure what.
That was leading back to lastcontinuehandler to print a larger
stack trace, and then the throwing = 1 print added runtime.abort,
which made TestAbort pass even though it wasn't really working.

Recognize abort properly and handle it as Go, not as something
for Windows to try to handle.

Keep the throwing = 1 print, because more detail on throw is
always better.

This CL is part of a stack adding windows/arm64
support (#36439), intended to land in the Go 1.17 cycle.
This CL is, however, not windows/arm64-specific.
It is cleanup meant to make the port (and future ports) easier.

Change-Id: If614f4ab2884bd90410d29e28311bf969ceeac09
Reviewed-on: https://go-review.googlesource.com/c/go/+/288810
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
src/runtime/signal_windows.go

index 89d12617f4d644a0f2993ef96f12bf69bcb8c511..18834b0ec57ffc65308a9c4fa9550c4e482161f0 100644 (file)
@@ -43,13 +43,17 @@ func initExceptionHandler() {
 //
 //go:nosplit
 func isAbort(r *context) bool {
-       // In the case of an abort, the exception IP is one byte after
-       // the INT3 (this differs from UNIX OSes).
-       return isAbortPC(r.ip() - 1)
+       pc := r.ip()
+       if GOARCH == "386" || GOARCH == "amd64" {
+               // In the case of an abort, the exception IP is one byte after
+               // the INT3 (this differs from UNIX OSes).
+               pc--
+       }
+       return isAbortPC(pc)
 }
 
 // isgoexception reports whether this exception should be translated
-// into a Go panic.
+// into a Go panic or throw.
 //
 // It is nosplit to avoid growing the stack in case we're aborting
 // because of a stack overflow.
@@ -63,11 +67,6 @@ func isgoexception(info *exceptionrecord, r *context) bool {
                return false
        }
 
-       if isAbort(r) {
-               // Never turn abort into a panic.
-               return false
-       }
-
        // Go will only handle some exceptions.
        switch info.exceptioncode {
        default:
@@ -99,14 +98,16 @@ func exceptionhandler(info *exceptionrecord, r *context, gp *g) int32 {
                return _EXCEPTION_CONTINUE_SEARCH
        }
 
-       // After this point, it is safe to grow the stack.
-
-       if gp.throwsplit {
-               // We can't safely sigpanic because it may grow the
-               // stack. Let it fall through.
-               return _EXCEPTION_CONTINUE_SEARCH
+       if gp.throwsplit || isAbort(r) {
+               // We can't safely sigpanic because it may grow the stack.
+               // Or this is a call to abort.
+               // Don't go through any more of the Windows handler chain.
+               // Crash now.
+               winthrow(info, r, gp)
        }
 
+       // After this point, it is safe to grow the stack.
+
        // Make it look like a call to the signal func.
        // Have to pass arguments out of band since
        // augmenting the stack frame would break
@@ -181,6 +182,12 @@ func lastcontinuehandler(info *exceptionrecord, r *context, gp *g) int32 {
                return _EXCEPTION_CONTINUE_SEARCH
        }
 
+       winthrow(info, r, gp)
+       return 0 // not reached
+}
+
+//go:nosplit
+func winthrow(info *exceptionrecord, r *context, gp *g) {
        _g_ := getg()
 
        if panicking != 0 { // traceback already printed
@@ -206,11 +213,8 @@ func lastcontinuehandler(info *exceptionrecord, r *context, gp *g) int32 {
        }
        print("\n")
 
-       // TODO(jordanrh1): This may be needed for 386/AMD64 as well.
-       if GOARCH == "arm" {
-               _g_.m.throwing = 1
-               _g_.m.caughtsig.set(gp)
-       }
+       _g_.m.throwing = 1
+       _g_.m.caughtsig.set(gp)
 
        level, _, docrash := gotraceback()
        if level > 0 {
@@ -224,7 +228,6 @@ func lastcontinuehandler(info *exceptionrecord, r *context, gp *g) int32 {
        }
 
        exit(2)
-       return 0 // not reached
 }
 
 func sigpanic() {