mirror of
https://github.com/golang/go
synced 2024-09-04 23:44:16 +00:00
runtime: fix backtrace during C syscalls for aix/ppc64
This commit fixes backtrace if a crash or an exit signal is received during a C syscall on aix/ppc64. This is similar to Solaris, Darwin or Windows implementation. Change-Id: I6040c0b1577a9f5b298f58bd4ee6556258a135ef Reviewed-on: https://go-review.googlesource.com/c/154718 Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
parent
cebf9d47cf
commit
3855fe7254
|
@ -151,91 +151,224 @@ var asmsyscall6 libFunc
|
|||
//go:nowritebarrier
|
||||
//go:nosplit
|
||||
func syscall0(fn *libFunc) (r, err uintptr) {
|
||||
c := &getg().m.libcall
|
||||
gp := getg()
|
||||
var mp *m
|
||||
if gp != nil {
|
||||
mp = gp.m
|
||||
}
|
||||
if mp != nil && mp.libcallsp == 0 {
|
||||
mp.libcallg.set(gp)
|
||||
mp.libcallpc = getcallerpc()
|
||||
// sp must be the last, because once async cpu profiler finds
|
||||
// all three values to be non-zero, it will use them
|
||||
mp.libcallsp = getcallersp()
|
||||
} else {
|
||||
mp = nil // See comment in sys_darwin.go:libcCall
|
||||
}
|
||||
|
||||
c := &gp.m.libcall
|
||||
c.fn = uintptr(unsafe.Pointer(fn))
|
||||
c.n = 0
|
||||
c.args = uintptr(noescape(unsafe.Pointer(&fn))) // it's unused but must be non-nil, otherwise crashes
|
||||
|
||||
asmcgocall(unsafe.Pointer(&asmsyscall6), unsafe.Pointer(c))
|
||||
|
||||
if mp != nil {
|
||||
mp.libcallsp = 0
|
||||
}
|
||||
|
||||
return c.r1, c.err
|
||||
}
|
||||
|
||||
//go:nowritebarrier
|
||||
//go:nosplit
|
||||
func syscall1(fn *libFunc, a0 uintptr) (r, err uintptr) {
|
||||
c := &getg().m.libcall
|
||||
gp := getg()
|
||||
var mp *m
|
||||
if gp != nil {
|
||||
mp = gp.m
|
||||
}
|
||||
if mp != nil && mp.libcallsp == 0 {
|
||||
mp.libcallg.set(gp)
|
||||
mp.libcallpc = getcallerpc()
|
||||
// sp must be the last, because once async cpu profiler finds
|
||||
// all three values to be non-zero, it will use them
|
||||
mp.libcallsp = getcallersp()
|
||||
} else {
|
||||
mp = nil // See comment in sys_darwin.go:libcCall
|
||||
}
|
||||
|
||||
c := &gp.m.libcall
|
||||
c.fn = uintptr(unsafe.Pointer(fn))
|
||||
c.n = 1
|
||||
c.args = uintptr(noescape(unsafe.Pointer(&a0)))
|
||||
|
||||
asmcgocall(unsafe.Pointer(&asmsyscall6), unsafe.Pointer(c))
|
||||
|
||||
if mp != nil {
|
||||
mp.libcallsp = 0
|
||||
}
|
||||
|
||||
return c.r1, c.err
|
||||
}
|
||||
|
||||
//go:nowritebarrier
|
||||
//go:nosplit
|
||||
func syscall2(fn *libFunc, a0, a1 uintptr) (r, err uintptr) {
|
||||
c := &getg().m.libcall
|
||||
gp := getg()
|
||||
var mp *m
|
||||
if gp != nil {
|
||||
mp = gp.m
|
||||
}
|
||||
if mp != nil && mp.libcallsp == 0 {
|
||||
mp.libcallg.set(gp)
|
||||
mp.libcallpc = getcallerpc()
|
||||
// sp must be the last, because once async cpu profiler finds
|
||||
// all three values to be non-zero, it will use them
|
||||
mp.libcallsp = getcallersp()
|
||||
} else {
|
||||
mp = nil // See comment in sys_darwin.go:libcCall
|
||||
}
|
||||
|
||||
c := &gp.m.libcall
|
||||
c.fn = uintptr(unsafe.Pointer(fn))
|
||||
c.n = 2
|
||||
c.args = uintptr(noescape(unsafe.Pointer(&a0)))
|
||||
|
||||
asmcgocall(unsafe.Pointer(&asmsyscall6), unsafe.Pointer(c))
|
||||
|
||||
if mp != nil {
|
||||
mp.libcallsp = 0
|
||||
}
|
||||
|
||||
return c.r1, c.err
|
||||
}
|
||||
|
||||
//go:nowritebarrier
|
||||
//go:nosplit
|
||||
func syscall3(fn *libFunc, a0, a1, a2 uintptr) (r, err uintptr) {
|
||||
c := &getg().m.libcall
|
||||
gp := getg()
|
||||
var mp *m
|
||||
if gp != nil {
|
||||
mp = gp.m
|
||||
}
|
||||
if mp != nil && mp.libcallsp == 0 {
|
||||
mp.libcallg.set(gp)
|
||||
mp.libcallpc = getcallerpc()
|
||||
// sp must be the last, because once async cpu profiler finds
|
||||
// all three values to be non-zero, it will use them
|
||||
mp.libcallsp = getcallersp()
|
||||
} else {
|
||||
mp = nil // See comment in sys_darwin.go:libcCall
|
||||
}
|
||||
|
||||
c := &gp.m.libcall
|
||||
c.fn = uintptr(unsafe.Pointer(fn))
|
||||
c.n = 3
|
||||
c.args = uintptr(noescape(unsafe.Pointer(&a0)))
|
||||
|
||||
asmcgocall(unsafe.Pointer(&asmsyscall6), unsafe.Pointer(c))
|
||||
|
||||
if mp != nil {
|
||||
mp.libcallsp = 0
|
||||
}
|
||||
|
||||
return c.r1, c.err
|
||||
}
|
||||
|
||||
//go:nowritebarrier
|
||||
//go:nosplit
|
||||
func syscall4(fn *libFunc, a0, a1, a2, a3 uintptr) (r, err uintptr) {
|
||||
c := &getg().m.libcall
|
||||
gp := getg()
|
||||
var mp *m
|
||||
if gp != nil {
|
||||
mp = gp.m
|
||||
}
|
||||
if mp != nil && mp.libcallsp == 0 {
|
||||
mp.libcallg.set(gp)
|
||||
mp.libcallpc = getcallerpc()
|
||||
// sp must be the last, because once async cpu profiler finds
|
||||
// all three values to be non-zero, it will use them
|
||||
mp.libcallsp = getcallersp()
|
||||
} else {
|
||||
mp = nil // See comment in sys_darwin.go:libcCall
|
||||
}
|
||||
|
||||
c := &gp.m.libcall
|
||||
c.fn = uintptr(unsafe.Pointer(fn))
|
||||
c.n = 4
|
||||
c.args = uintptr(noescape(unsafe.Pointer(&a0)))
|
||||
|
||||
asmcgocall(unsafe.Pointer(&asmsyscall6), unsafe.Pointer(c))
|
||||
|
||||
if mp != nil {
|
||||
mp.libcallsp = 0
|
||||
}
|
||||
|
||||
return c.r1, c.err
|
||||
}
|
||||
|
||||
//go:nowritebarrier
|
||||
//go:nosplit
|
||||
func syscall5(fn *libFunc, a0, a1, a2, a3, a4 uintptr) (r, err uintptr) {
|
||||
c := &getg().m.libcall
|
||||
gp := getg()
|
||||
var mp *m
|
||||
if gp != nil {
|
||||
mp = gp.m
|
||||
}
|
||||
if mp != nil && mp.libcallsp == 0 {
|
||||
mp.libcallg.set(gp)
|
||||
mp.libcallpc = getcallerpc()
|
||||
// sp must be the last, because once async cpu profiler finds
|
||||
// all three values to be non-zero, it will use them
|
||||
mp.libcallsp = getcallersp()
|
||||
} else {
|
||||
mp = nil // See comment in sys_darwin.go:libcCall
|
||||
}
|
||||
|
||||
c := &gp.m.libcall
|
||||
c.fn = uintptr(unsafe.Pointer(fn))
|
||||
c.n = 5
|
||||
c.args = uintptr(noescape(unsafe.Pointer(&a0)))
|
||||
|
||||
asmcgocall(unsafe.Pointer(&asmsyscall6), unsafe.Pointer(c))
|
||||
|
||||
if mp != nil {
|
||||
mp.libcallsp = 0
|
||||
}
|
||||
|
||||
return c.r1, c.err
|
||||
}
|
||||
|
||||
//go:nowritebarrier
|
||||
//go:nosplit
|
||||
func syscall6(fn *libFunc, a0, a1, a2, a3, a4, a5 uintptr) (r, err uintptr) {
|
||||
c := &getg().m.libcall
|
||||
gp := getg()
|
||||
var mp *m
|
||||
if gp != nil {
|
||||
mp = gp.m
|
||||
}
|
||||
if mp != nil && mp.libcallsp == 0 {
|
||||
mp.libcallg.set(gp)
|
||||
mp.libcallpc = getcallerpc()
|
||||
// sp must be the last, because once async cpu profiler finds
|
||||
// all three values to be non-zero, it will use them
|
||||
mp.libcallsp = getcallersp()
|
||||
} else {
|
||||
mp = nil // See comment in sys_darwin.go:libcCall
|
||||
}
|
||||
|
||||
c := &gp.m.libcall
|
||||
c.fn = uintptr(unsafe.Pointer(fn))
|
||||
c.n = 6
|
||||
c.args = uintptr(noescape(unsafe.Pointer(&a0)))
|
||||
|
||||
asmcgocall(unsafe.Pointer(&asmsyscall6), unsafe.Pointer(c))
|
||||
|
||||
if mp != nil {
|
||||
mp.libcallsp = 0
|
||||
}
|
||||
|
||||
return c.r1, c.err
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue