]> Cypherpunks.ru repositories - gostls13.git/commitdiff
runtime: improve sigtramp on aix/ppc64 to handle SIGPROF
authorClément Chigot <clement.chigot@atos.net>
Mon, 25 Mar 2019 09:26:44 +0000 (10:26 +0100)
committerIan Lance Taylor <iant@golang.org>
Tue, 26 Mar 2019 20:04:42 +0000 (20:04 +0000)
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>
src/runtime/crash_cgo_test.go
src/runtime/crash_test.go
src/runtime/os_aix.go
src/runtime/pprof/pprof_test.go
src/runtime/pprof/proto_test.go
src/runtime/proc.go
src/runtime/sys_aix_ppc64.s

index 07eba78c8af470c3b51864f11d5bc0113e797678..af3c1f82a7528dc63a70e83a2d8266124f7be99a 100644 (file)
@@ -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"
index 03ebf022a6ef8d02aa94e4c9ff3be219f88090f5..c54bb57da2ee0b28119ae2f37d67552c60e531e3 100644 (file)
@@ -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)
index 141ce3bb119564cba10d242166668d025aeaa7a3..45c7174e058479038aed97b3ed7de2ff70fd33c1 100644 (file)
@@ -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)
 }
index 7c6043ffdb2e830cbe39b38586d1f3a123c01ac1..964e83abc6e21b77221a4593f6dd2ac67cd07c1e 100644 (file)
@@ -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
 
index cb38150da8ce045b62fec47053883dbb12487360..4452d5123158e5c40af264536d92a21624000ddc 100644 (file)
@@ -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.
index a077a5da03012104c00557fe659d17e0df81c4a0..9e993afba925a2ba44b4df9bf88acef91dffedf0 100644 (file)
@@ -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)
index ee572cb4deb5588492d14dc18b8ab06e2c879f23..65fcae0c0c6620d0f447c618223416bea64943fc 100644 (file)
@@ -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)