mirror of
https://github.com/golang/go
synced 2024-10-14 03:43:28 +00:00
runtime: merge sigpanic_unix.go into signal_unix.go
Change-Id: Iba541045b4878405834c637095627631b6559a35 Reviewed-on: https://go-review.googlesource.com/29754 Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
parent
38765eba73
commit
343bec53c7
|
@ -196,6 +196,49 @@ func sigpipe() {
|
|||
dieFromSignal(_SIGPIPE)
|
||||
}
|
||||
|
||||
// sigpanic turns a synchronous signal into a run-time panic.
|
||||
// If the signal handler sees a synchronous panic, it arranges the
|
||||
// stack to look like the function where the signal occurred called
|
||||
// sigpanic, sets the signal's PC value to sigpanic, and returns from
|
||||
// the signal handler. The effect is that the program will act as
|
||||
// though the function that got the signal simply called sigpanic
|
||||
// instead.
|
||||
func sigpanic() {
|
||||
g := getg()
|
||||
if !canpanic(g) {
|
||||
throw("unexpected signal during runtime execution")
|
||||
}
|
||||
|
||||
switch g.sig {
|
||||
case _SIGBUS:
|
||||
if g.sigcode0 == _BUS_ADRERR && g.sigcode1 < 0x1000 || g.paniconfault {
|
||||
panicmem()
|
||||
}
|
||||
print("unexpected fault address ", hex(g.sigcode1), "\n")
|
||||
throw("fault")
|
||||
case _SIGSEGV:
|
||||
if (g.sigcode0 == 0 || g.sigcode0 == _SEGV_MAPERR || g.sigcode0 == _SEGV_ACCERR) && g.sigcode1 < 0x1000 || g.paniconfault {
|
||||
panicmem()
|
||||
}
|
||||
print("unexpected fault address ", hex(g.sigcode1), "\n")
|
||||
throw("fault")
|
||||
case _SIGFPE:
|
||||
switch g.sigcode0 {
|
||||
case _FPE_INTDIV:
|
||||
panicdivide()
|
||||
case _FPE_INTOVF:
|
||||
panicoverflow()
|
||||
}
|
||||
panicfloat()
|
||||
}
|
||||
|
||||
if g.sig >= uint32(len(sigtable)) {
|
||||
// can't happen: we looked up g.sig in sigtable to decide to call sigpanic
|
||||
throw("unexpected signal value")
|
||||
}
|
||||
panic(errorString(sigtable[g.sig].name))
|
||||
}
|
||||
|
||||
// dieFromSignal kills the program with a signal.
|
||||
// This provides the expected exit status for the shell.
|
||||
// This is only called with fatal signals expected to kill the process.
|
||||
|
@ -473,3 +516,13 @@ func unblocksig(sig int32) {
|
|||
set := sigmaskToSigset(m)
|
||||
sigprocmask(_SIG_UNBLOCK, &set, nil)
|
||||
}
|
||||
|
||||
// setsigsegv is used on darwin/arm{,64} to fake a segmentation fault.
|
||||
//go:nosplit
|
||||
func setsigsegv(pc uintptr) {
|
||||
g := getg()
|
||||
g.sig = _SIGSEGV
|
||||
g.sigpc = pc
|
||||
g.sigcode0 = _SEGV_MAPERR
|
||||
g.sigcode1 = 0 // TODO: emulate si_addr
|
||||
}
|
||||
|
|
|
@ -1,53 +0,0 @@
|
|||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build darwin dragonfly freebsd linux netbsd openbsd solaris
|
||||
|
||||
package runtime
|
||||
|
||||
func sigpanic() {
|
||||
g := getg()
|
||||
if !canpanic(g) {
|
||||
throw("unexpected signal during runtime execution")
|
||||
}
|
||||
|
||||
switch g.sig {
|
||||
case _SIGBUS:
|
||||
if g.sigcode0 == _BUS_ADRERR && g.sigcode1 < 0x1000 || g.paniconfault {
|
||||
panicmem()
|
||||
}
|
||||
print("unexpected fault address ", hex(g.sigcode1), "\n")
|
||||
throw("fault")
|
||||
case _SIGSEGV:
|
||||
if (g.sigcode0 == 0 || g.sigcode0 == _SEGV_MAPERR || g.sigcode0 == _SEGV_ACCERR) && g.sigcode1 < 0x1000 || g.paniconfault {
|
||||
panicmem()
|
||||
}
|
||||
print("unexpected fault address ", hex(g.sigcode1), "\n")
|
||||
throw("fault")
|
||||
case _SIGFPE:
|
||||
switch g.sigcode0 {
|
||||
case _FPE_INTDIV:
|
||||
panicdivide()
|
||||
case _FPE_INTOVF:
|
||||
panicoverflow()
|
||||
}
|
||||
panicfloat()
|
||||
}
|
||||
|
||||
if g.sig >= uint32(len(sigtable)) {
|
||||
// can't happen: we looked up g.sig in sigtable to decide to call sigpanic
|
||||
throw("unexpected signal value")
|
||||
}
|
||||
panic(errorString(sigtable[g.sig].name))
|
||||
}
|
||||
|
||||
// setsigsegv is used on darwin/arm{,64} to fake a segmentation fault.
|
||||
//go:nosplit
|
||||
func setsigsegv(pc uintptr) {
|
||||
g := getg()
|
||||
g.sig = _SIGSEGV
|
||||
g.sigpc = pc
|
||||
g.sigcode0 = _SEGV_MAPERR
|
||||
g.sigcode1 = 0 // TODO: emulate si_addr
|
||||
}
|
Loading…
Reference in a new issue