mirror of
https://github.com/golang/go
synced 2024-11-17 11:14:46 -07:00
runtime: crash earlier on windows for runtime.abort
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>
This commit is contained in:
parent
a1e9148e3d
commit
38672d3dcf
@ -43,13 +43,17 @@ func initExceptionHandler() {
|
||||
//
|
||||
//go:nosplit
|
||||
func isAbort(r *context) bool {
|
||||
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).
|
||||
return isAbortPC(r.ip() - 1)
|
||||
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)
|
||||
}
|
||||
|
||||
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() {
|
||||
|
Loading…
Reference in New Issue
Block a user