]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: use per-thread profiler for SetCgoTraceback platforms
authorRhys Hiltner <rhys@justin.tv>
Fri, 13 Aug 2021 16:01:13 +0000 (09:01 -0700)
committerMichael Pratt <mpratt@google.com>
Mon, 27 Sep 2021 18:58:41 +0000 (18:58 +0000)
Updates #35057

Change-Id: I61d772a2cbfb27540fb70c14676c68593076ca94
Reviewed-on: https://go-review.googlesource.com/c/go/+/342054
Run-TryBot: Rhys Hiltner <rhys@justin.tv>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Michael Pratt <mpratt@google.com>
Trust: Michael Knyszek <mknyszek@google.com>

src/runtime/os_linux.go
src/runtime/signal_unix.go
src/runtime/sys_darwin_amd64.s
src/runtime/sys_freebsd_amd64.s
src/runtime/sys_linux_amd64.s
src/runtime/sys_linux_ppc64x.s

index a4646577cbfe5823298e04bc21e3bf4853cb57d0..06773c21939404f28abc7140dd055064402edbda 100644 (file)
@@ -529,10 +529,8 @@ func signalM(mp *m, sig int) {
        tgkill(getpid(), int(mp.procid), sig)
 }
 
-// go118UseTimerCreateProfiler enables the per-thread CPU profiler. Platforms
-// with support for SetCgoTraceback do some signal handling in assembly; do not
-// enable it for them until the changes to those code paths are in place.
-const go118UseTimerCreateProfiler = GOARCH != "amd64" && GOARCH != "ppc64le"
+// go118UseTimerCreateProfiler enables the per-thread CPU profiler.
+const go118UseTimerCreateProfiler = true
 
 // validSIGPROF compares this signal delivery's code against the signal sources
 // that the profiler uses, returning whether the delivery should be processed.
index 0b32598d54accc0a31f834d543643b72978e02d5..07f371cefe0c402afa267ac62362e0bfb74fdd4d 100644 (file)
@@ -480,15 +480,26 @@ var sigprofCallersUse uint32
 // and the signal handler collected a stack trace in sigprofCallers.
 // When this is called, sigprofCallersUse will be non-zero.
 // g is nil, and what we can do is very limited.
+//
+// It is called from the signal handling functions written in assembly code that
+// are active for cgo programs, cgoSigtramp and sigprofNonGoWrapper, which have
+// not verified that the SIGPROF delivery corresponds to the best available
+// profiling source for this thread.
+//
 //go:nosplit
 //go:nowritebarrierrec
-func sigprofNonGo() {
+func sigprofNonGo(sig uint32, info *siginfo, ctx unsafe.Pointer) {
        if prof.hz != 0 {
-               n := 0
-               for n < len(sigprofCallers) && sigprofCallers[n] != 0 {
-                       n++
+               c := &sigctxt{info, ctx}
+               // Some platforms (Linux) have per-thread timers, which we use in
+               // combination with the process-wide timer. Avoid double-counting.
+               if validSIGPROF(nil, c) {
+                       n := 0
+                       for n < len(sigprofCallers) && sigprofCallers[n] != 0 {
+                               n++
+                       }
+                       cpuprof.addNonGo(sigprofCallers[:n])
                }
-               cpuprof.addNonGo(sigprofCallers[:n])
        }
 
        atomic.Store(&sigprofCallersUse, 0)
index 3bd027f98242f06d189643af0af0c3e8a1931b6c..5d89cda8e68901a668fec3e3b7bb7f30e21b3e57 100644 (file)
@@ -230,6 +230,23 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$0
        POP_REGS_HOST_TO_ABI0()
        RET
 
+// Called using C ABI.
+TEXT runtime·sigprofNonGoWrapper<>(SB),NOSPLIT,$0
+       // Transition from C ABI to Go ABI.
+       PUSH_REGS_HOST_TO_ABI0()
+
+       // Call into the Go signal handler
+       NOP     SP              // disable vet stack checking
+       ADJSP   $24
+       MOVL    DI, 0(SP)       // sig
+       MOVQ    SI, 8(SP)       // info
+       MOVQ    DX, 16(SP)      // ctx
+       CALL    ·sigprofNonGo(SB)
+       ADJSP   $-24
+
+       POP_REGS_HOST_TO_ABI0()
+       RET
+
 // Used instead of sigtramp in programs that use cgo.
 // Arguments from kernel are in DI, SI, DX.
 TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0
@@ -297,12 +314,12 @@ sigtrampnog:
        JNZ     sigtramp  // Skip stack trace if already locked.
 
        // Jump to the traceback function in runtime/cgo.
-       // It will call back to sigprofNonGo, which will ignore the
-       // arguments passed in registers.
+       // It will call back to sigprofNonGo, via sigprofNonGoWrapper, to convert
+       // the arguments to the Go calling convention.
        // First three arguments to traceback function are in registers already.
        MOVQ    runtime·cgoTraceback(SB), CX
        MOVQ    $runtime·sigprofCallers(SB), R8
-       MOVQ    $runtime·sigprofNonGo(SB), R9
+       MOVQ    $runtime·sigprofNonGoWrapper<>(SB), R9
        MOVQ    _cgo_callers(SB), AX
        JMP     AX
 
index 71a60cae65c23668ba2638592566a96b2e383914..165e97c60d735881ea3797df151f5c3aa79f9409 100644 (file)
@@ -255,6 +255,23 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$0
         POP_REGS_HOST_TO_ABI0()
        RET
 
+// Called using C ABI.
+TEXT runtime·sigprofNonGoWrapper<>(SB),NOSPLIT,$0
+       // Transition from C ABI to Go ABI.
+       PUSH_REGS_HOST_TO_ABI0()
+
+       // Call into the Go signal handler
+       NOP     SP              // disable vet stack checking
+       ADJSP   $24
+       MOVL    DI, 0(SP)       // sig
+       MOVQ    SI, 8(SP)       // info
+       MOVQ    DX, 16(SP)      // ctx
+       CALL    ·sigprofNonGo(SB)
+       ADJSP   $-24
+
+       POP_REGS_HOST_TO_ABI0()
+       RET
+
 // Used instead of sigtramp in programs that use cgo.
 // Arguments from kernel are in DI, SI, DX.
 TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0
@@ -322,12 +339,12 @@ sigtrampnog:
        JNZ     sigtramp  // Skip stack trace if already locked.
 
        // Jump to the traceback function in runtime/cgo.
-       // It will call back to sigprofNonGo, which will ignore the
-       // arguments passed in registers.
+       // It will call back to sigprofNonGo, via sigprofNonGoWrapper, to convert
+       // the arguments to the Go calling convention.
        // First three arguments to traceback function are in registers already.
        MOVQ    runtime·cgoTraceback(SB), CX
        MOVQ    $runtime·sigprofCallers(SB), R8
-       MOVQ    $runtime·sigprofNonGo(SB), R9
+       MOVQ    $runtime·sigprofNonGoWrapper<>(SB), R9
        MOVQ    _cgo_callers(SB), AX
        JMP     AX
 
index 345dc90eb0763d024f273ae374638b67bc4a6eee..f0e58e11db36ec56ed0bf2de730f198a64cec0a3 100644 (file)
@@ -364,6 +364,23 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$0
         POP_REGS_HOST_TO_ABI0()
        RET
 
+// Called using C ABI.
+TEXT runtime·sigprofNonGoWrapper<>(SB),NOSPLIT,$0
+       // Transition from C ABI to Go ABI.
+       PUSH_REGS_HOST_TO_ABI0()
+
+       // Call into the Go signal handler
+       NOP     SP              // disable vet stack checking
+       ADJSP   $24
+       MOVL    DI, 0(SP)       // sig
+       MOVQ    SI, 8(SP)       // info
+       MOVQ    DX, 16(SP)      // ctx
+       CALL    ·sigprofNonGo(SB)
+       ADJSP   $-24
+
+       POP_REGS_HOST_TO_ABI0()
+       RET
+
 // Used instead of sigtramp in programs that use cgo.
 // Arguments from kernel are in DI, SI, DX.
 TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0
@@ -431,12 +448,12 @@ sigtrampnog:
        JNZ     sigtramp  // Skip stack trace if already locked.
 
        // Jump to the traceback function in runtime/cgo.
-       // It will call back to sigprofNonGo, which will ignore the
-       // arguments passed in registers.
+       // It will call back to sigprofNonGo, via sigprofNonGoWrapper, to convert
+       // the arguments to the Go calling convention.
        // First three arguments to traceback function are in registers already.
        MOVQ    runtime·cgoTraceback(SB), CX
        MOVQ    $runtime·sigprofCallers(SB), R8
-       MOVQ    $runtime·sigprofNonGo(SB), R9
+       MOVQ    $runtime·sigprofNonGoWrapper<>(SB), R9
        MOVQ    _cgo_callers(SB), AX
        JMP     AX
 
index 56d600b6eaa7e54d65ece89e33400d228fe65576..9347afaf19086b4d189375f698b67d3efe8ed5c8 100644 (file)
@@ -743,6 +743,9 @@ TEXT cgoSigtramp<>(SB),NOSPLIT,$0
 TEXT runtime·sigprofNonGoWrapper<>(SB),NOSPLIT,$0
        // We're coming from C code, set up essential register, then call sigprofNonGo.
        CALL    runtime·reginit(SB)
+       MOVW    R3, FIXED_FRAME+0(R1)   // sig
+       MOVD    R4, FIXED_FRAME+8(R1)   // info
+       MOVD    R5, FIXED_FRAME+16(R1)  // ctx
        CALL    runtime·sigprofNonGo(SB)
        RET