aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClément Chigot <clement.chigot@atos.net>2019-03-25 10:26:44 +0100
committerIan Lance Taylor <iant@golang.org>2019-03-26 20:04:42 +0000
commitb5cf035d1ca21ee4bf799c6d97b2759471b76483 (patch)
tree186ed54996563dae3e6e7716181e92c17c01f105
parente007916cea969c4d5917da931413fba4eb43e8f6 (diff)
downloadgo-b5cf035d1ca21ee4bf799c6d97b2759471b76483.tar.gz
go-b5cf035d1ca21ee4bf799c6d97b2759471b76483.zip
runtime: improve sigtramp on aix/ppc64 to handle SIGPROF
R14, R15 must be saved in sigtramp because they might be modified by Go code when a SIGPROF occurs. Fixes #28555 Change-Id: I573541f108d7d6aac8e60d33c649e5db943f3ef5 Reviewed-on: https://go-review.googlesource.com/c/go/+/169117 Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
-rw-r--r--src/runtime/crash_cgo_test.go3
-rw-r--r--src/runtime/crash_test.go3
-rw-r--r--src/runtime/os_aix.go2
-rw-r--r--src/runtime/pprof/pprof_test.go2
-rw-r--r--src/runtime/pprof/proto_test.go4
-rw-r--r--src/runtime/proc.go2
-rw-r--r--src/runtime/sys_aix_ppc64.s60
7 files changed, 33 insertions, 43 deletions
diff --git a/src/runtime/crash_cgo_test.go b/src/runtime/crash_cgo_test.go
index 07eba78c8a..af3c1f82a7 100644
--- a/src/runtime/crash_cgo_test.go
+++ b/src/runtime/crash_cgo_test.go
@@ -229,9 +229,6 @@ func TestCgoPanicDeadlock(t *testing.T) {
}
func TestCgoCCodeSIGPROF(t *testing.T) {
- if runtime.GOOS == "aix" {
- t.Skip("pprof not yet available on AIX (see golang.org/issue/28555)")
- }
t.Parallel()
got := runTestProg(t, "testprogcgo", "CgoCCodeSIGPROF")
want := "OK\n"
diff --git a/src/runtime/crash_test.go b/src/runtime/crash_test.go
index 03ebf022a6..c54bb57da2 100644
--- a/src/runtime/crash_test.go
+++ b/src/runtime/crash_test.go
@@ -623,9 +623,6 @@ func TestBadTraceback(t *testing.T) {
}
func TestTimePprof(t *testing.T) {
- if runtime.GOOS == "aix" {
- t.Skip("pprof not yet available on AIX (see golang.org/issue/28555)")
- }
fn := runTestProg(t, "testprog", "TimeProf")
fn = strings.TrimSpace(fn)
defer os.Remove(fn)
diff --git a/src/runtime/os_aix.go b/src/runtime/os_aix.go
index 141ce3bb11..45c7174e05 100644
--- a/src/runtime/os_aix.go
+++ b/src/runtime/os_aix.go
@@ -233,6 +233,8 @@ func setSignalstackSP(s *stackt, sp uintptr) {
func (c *sigctxt) fixsigcode(sig uint32) {
}
+//go:nosplit
+//go:nowritebarrierrec
func sigaddset(mask *sigset, i int) {
(*mask)[(i-1)/64] |= 1 << ((uint32(i) - 1) & 63)
}
diff --git a/src/runtime/pprof/pprof_test.go b/src/runtime/pprof/pprof_test.go
index 7c6043ffdb..964e83abc6 100644
--- a/src/runtime/pprof/pprof_test.go
+++ b/src/runtime/pprof/pprof_test.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !aix,!nacl,!js
+// +build !nacl,!js
package pprof
diff --git a/src/runtime/pprof/proto_test.go b/src/runtime/pprof/proto_test.go
index cb38150da8..4452d51231 100644
--- a/src/runtime/pprof/proto_test.go
+++ b/src/runtime/pprof/proto_test.go
@@ -312,10 +312,6 @@ func TestMapping(t *testing.T) {
testenv.MustHaveGoRun(t)
testenv.MustHaveCGO(t)
- if runtime.GOOS == "aix" {
- t.Skip("pprof not yet available on AIX (see golang.org/issue/28555)")
- }
-
prog := "./testdata/mappingtest/main.go"
// GoOnly includes only Go symbols that runtime will symbolize.
diff --git a/src/runtime/proc.go b/src/runtime/proc.go
index a077a5da03..9e993afba9 100644
--- a/src/runtime/proc.go
+++ b/src/runtime/proc.go
@@ -3758,7 +3758,7 @@ func sigprof(pc, sp, lr uintptr, gp *g, mp *m) {
// Normal traceback is impossible or has failed.
// See if it falls into several common cases.
n = 0
- if (GOOS == "windows" || GOOS == "solaris" || GOOS == "darwin") && mp.libcallg != 0 && mp.libcallpc != 0 && mp.libcallsp != 0 {
+ if (GOOS == "windows" || GOOS == "solaris" || GOOS == "darwin" || GOOS == "aix") && mp.libcallg != 0 && mp.libcallpc != 0 && mp.libcallsp != 0 {
// Libcall, i.e. runtime syscall on windows.
// Collect Go stack that leads to the call.
n = gentraceback(mp.libcallpc, mp.libcallsp, 0, mp.libcallg.ptr(), 0, &stk[0], len(stk), nil, nil, 0)
diff --git a/src/runtime/sys_aix_ppc64.s b/src/runtime/sys_aix_ppc64.s
index ee572cb4de..65fcae0c0c 100644
--- a/src/runtime/sys_aix_ppc64.s
+++ b/src/runtime/sys_aix_ppc64.s
@@ -97,6 +97,7 @@ GLOBL runtime·sigtramp(SB), NOPTR, $24
// This funcion must not have any frame as we want to control how
// every registers are used.
+// TODO(aix): Implement SetCgoTraceback handler.
TEXT runtime·_sigtramp(SB),NOSPLIT|NOFRAME,$0
MOVD LR, R0
MOVD R0, 16(R1)
@@ -107,39 +108,42 @@ TEXT runtime·_sigtramp(SB),NOSPLIT|NOFRAME,$0
// more stack available than NOSPLIT would have us believe.
// To defeat the linker, we make our own stack frame with
// more space.
- SUB $128+FIXED_FRAME, R1
+ SUB $144+FIXED_FRAME, R1
// Save registers
MOVD R31, 56(R1)
MOVD g, 64(R1)
MOVD R29, 72(R1)
+ MOVD R14, 80(R1)
+ MOVD R15, 88(R1)
BL runtime·load_g(SB)
CMP $0, g
- BEQ sigtrampnog // g == nil
+ BEQ sigtramp // g == nil
+ MOVD g_m(g), R6
+ CMP $0, R6
+ BEQ sigtramp // g.m == nil
// Save m->libcall. We need to do this because we
// might get interrupted by a signal in runtime·asmcgocall.
-
- // save m->libcall
- MOVD g_m(g), R6
MOVD (m_libcall+libcall_fn)(R6), R7
- MOVD R7, 80(R1)
+ MOVD R7, 96(R1)
MOVD (m_libcall+libcall_args)(R6), R7
- MOVD R7, 88(R1)
+ MOVD R7, 104(R1)
MOVD (m_libcall+libcall_n)(R6), R7
- MOVD R7, 96(R1)
+ MOVD R7, 112(R1)
MOVD (m_libcall+libcall_r1)(R6), R7
- MOVD R7, 104(R1)
+ MOVD R7, 120(R1)
MOVD (m_libcall+libcall_r2)(R6), R7
- MOVD R7, 112(R1)
+ MOVD R7, 128(R1)
// save errno, it might be EINTR; stuff we do here might reset it.
MOVD (m_mOS+mOS_perrno)(R6), R8
MOVD 0(R8), R8
- MOVD R8, 120(R1)
+ MOVD R8, 136(R1)
+sigtramp:
MOVW R3, FIXED_FRAME+0(R1)
MOVD R4, FIXED_FRAME+8(R1)
MOVD R5, FIXED_FRAME+16(R1)
@@ -147,22 +151,27 @@ TEXT runtime·_sigtramp(SB),NOSPLIT|NOFRAME,$0
MOVD R12, CTR
BL (CTR)
+ CMP $0, g
+ BEQ exit // g == nil
MOVD g_m(g), R6
+ CMP $0, R6
+ BEQ exit // g.m == nil
+
// restore libcall
- MOVD 80(R1), R7
+ MOVD 96(R1), R7
MOVD R7, (m_libcall+libcall_fn)(R6)
- MOVD 88(R1), R7
+ MOVD 104(R1), R7
MOVD R7, (m_libcall+libcall_args)(R6)
- MOVD 96(R1), R7
+ MOVD 112(R1), R7
MOVD R7, (m_libcall+libcall_n)(R6)
- MOVD 104(R1), R7
+ MOVD 120(R1), R7
MOVD R7, (m_libcall+libcall_r1)(R6)
- MOVD 112(R1), R7
+ MOVD 128(R1), R7
MOVD R7, (m_libcall+libcall_r2)(R6)
// restore errno
MOVD (m_mOS+mOS_perrno)(R6), R7
- MOVD 120(R1), R8
+ MOVD 136(R1), R8
MOVD R8, 0(R7)
exit:
@@ -170,26 +179,15 @@ exit:
MOVD 56(R1),R31
MOVD 64(R1),g
MOVD 72(R1),R29
+ MOVD 80(R1), R14
+ MOVD 88(R1), R15
// Don't use RET because we need to restore R31 !
- ADD $128+FIXED_FRAME, R1
+ ADD $144+FIXED_FRAME, R1
MOVD 16(R1), R0
MOVD R0, LR
BR (LR)
-sigtrampnog:
- // Signal arrived on a non-Go thread.
- // SIGPROF handler is not yet available so simply call badsignal,
- // after having created *sigctxt.
- MOVD R4, 80(R1)
- MOVD R5, 88(R1)
- MOVD R1, R4
- ADD $80, R4
- MOVD R4, FIXED_FRAME+8(R1)
- MOVD R3, FIXED_FRAME+0(R1)
- BL runtime·badsignal(SB)
- JMP exit
-
// runtime.tstart is a function descriptor to the real tstart.
DATA runtime·tstart+0(SB)/8, $runtime·_tstart(SB)
DATA runtime·tstart+8(SB)/8, $TOC(SB)