Skip to content

Commit 8d09f7c

Browse files
rhyshprattmic
authored andcommitted
runtime: use per-thread profiler for SetCgoTraceback platforms
Updates #35057 Change-Id: I61d772a2cbfb27540fb70c14676c68593076ca94 Reviewed-on: https://go-review.googlesource.com/c/go/+/342054 Run-TryBot: Rhys Hiltner <[email protected]> TryBot-Result: Go Bot <[email protected]> Reviewed-by: Michael Pratt <[email protected]> Trust: Michael Knyszek <[email protected]>
1 parent 5b90958 commit 8d09f7c

File tree

6 files changed

+81
-18
lines changed

6 files changed

+81
-18
lines changed

src/runtime/os_linux.go

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -529,10 +529,8 @@ func signalM(mp *m, sig int) {
529529
tgkill(getpid(), int(mp.procid), sig)
530530
}
531531

532-
// go118UseTimerCreateProfiler enables the per-thread CPU profiler. Platforms
533-
// with support for SetCgoTraceback do some signal handling in assembly; do not
534-
// enable it for them until the changes to those code paths are in place.
535-
const go118UseTimerCreateProfiler = GOARCH != "amd64" && GOARCH != "ppc64le"
532+
// go118UseTimerCreateProfiler enables the per-thread CPU profiler.
533+
const go118UseTimerCreateProfiler = true
536534

537535
// validSIGPROF compares this signal delivery's code against the signal sources
538536
// that the profiler uses, returning whether the delivery should be processed.

src/runtime/signal_unix.go

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -480,15 +480,26 @@ var sigprofCallersUse uint32
480480
// and the signal handler collected a stack trace in sigprofCallers.
481481
// When this is called, sigprofCallersUse will be non-zero.
482482
// g is nil, and what we can do is very limited.
483+
//
484+
// It is called from the signal handling functions written in assembly code that
485+
// are active for cgo programs, cgoSigtramp and sigprofNonGoWrapper, which have
486+
// not verified that the SIGPROF delivery corresponds to the best available
487+
// profiling source for this thread.
488+
//
483489
//go:nosplit
484490
//go:nowritebarrierrec
485-
func sigprofNonGo() {
491+
func sigprofNonGo(sig uint32, info *siginfo, ctx unsafe.Pointer) {
486492
if prof.hz != 0 {
487-
n := 0
488-
for n < len(sigprofCallers) && sigprofCallers[n] != 0 {
489-
n++
493+
c := &sigctxt{info, ctx}
494+
// Some platforms (Linux) have per-thread timers, which we use in
495+
// combination with the process-wide timer. Avoid double-counting.
496+
if validSIGPROF(nil, c) {
497+
n := 0
498+
for n < len(sigprofCallers) && sigprofCallers[n] != 0 {
499+
n++
500+
}
501+
cpuprof.addNonGo(sigprofCallers[:n])
490502
}
491-
cpuprof.addNonGo(sigprofCallers[:n])
492503
}
493504

494505
atomic.Store(&sigprofCallersUse, 0)

src/runtime/sys_darwin_amd64.s

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,23 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$0
230230
POP_REGS_HOST_TO_ABI0()
231231
RET
232232

233+
// Called using C ABI.
234+
TEXT runtime·sigprofNonGoWrapper<>(SB),NOSPLIT,$0
235+
// Transition from C ABI to Go ABI.
236+
PUSH_REGS_HOST_TO_ABI0()
237+
238+
// Call into the Go signal handler
239+
NOP SP // disable vet stack checking
240+
ADJSP $24
241+
MOVL DI, 0(SP) // sig
242+
MOVQ SI, 8(SP) // info
243+
MOVQ DX, 16(SP) // ctx
244+
CALL ·sigprofNonGo(SB)
245+
ADJSP $-24
246+
247+
POP_REGS_HOST_TO_ABI0()
248+
RET
249+
233250
// Used instead of sigtramp in programs that use cgo.
234251
// Arguments from kernel are in DI, SI, DX.
235252
TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0
@@ -297,12 +314,12 @@ sigtrampnog:
297314
JNZ sigtramp // Skip stack trace if already locked.
298315

299316
// Jump to the traceback function in runtime/cgo.
300-
// It will call back to sigprofNonGo, which will ignore the
301-
// arguments passed in registers.
317+
// It will call back to sigprofNonGo, via sigprofNonGoWrapper, to convert
318+
// the arguments to the Go calling convention.
302319
// First three arguments to traceback function are in registers already.
303320
MOVQ runtime·cgoTraceback(SB), CX
304321
MOVQ $runtime·sigprofCallers(SB), R8
305-
MOVQ $runtime·sigprofNonGo(SB), R9
322+
MOVQ $runtime·sigprofNonGoWrapper<>(SB), R9
306323
MOVQ _cgo_callers(SB), AX
307324
JMP AX
308325

src/runtime/sys_freebsd_amd64.s

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,23 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$0
255255
POP_REGS_HOST_TO_ABI0()
256256
RET
257257

258+
// Called using C ABI.
259+
TEXT runtime·sigprofNonGoWrapper<>(SB),NOSPLIT,$0
260+
// Transition from C ABI to Go ABI.
261+
PUSH_REGS_HOST_TO_ABI0()
262+
263+
// Call into the Go signal handler
264+
NOP SP // disable vet stack checking
265+
ADJSP $24
266+
MOVL DI, 0(SP) // sig
267+
MOVQ SI, 8(SP) // info
268+
MOVQ DX, 16(SP) // ctx
269+
CALL ·sigprofNonGo(SB)
270+
ADJSP $-24
271+
272+
POP_REGS_HOST_TO_ABI0()
273+
RET
274+
258275
// Used instead of sigtramp in programs that use cgo.
259276
// Arguments from kernel are in DI, SI, DX.
260277
TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0
@@ -322,12 +339,12 @@ sigtrampnog:
322339
JNZ sigtramp // Skip stack trace if already locked.
323340

324341
// Jump to the traceback function in runtime/cgo.
325-
// It will call back to sigprofNonGo, which will ignore the
326-
// arguments passed in registers.
342+
// It will call back to sigprofNonGo, via sigprofNonGoWrapper, to convert
343+
// the arguments to the Go calling convention.
327344
// First three arguments to traceback function are in registers already.
328345
MOVQ runtime·cgoTraceback(SB), CX
329346
MOVQ $runtime·sigprofCallers(SB), R8
330-
MOVQ $runtime·sigprofNonGo(SB), R9
347+
MOVQ $runtime·sigprofNonGoWrapper<>(SB), R9
331348
MOVQ _cgo_callers(SB), AX
332349
JMP AX
333350

src/runtime/sys_linux_amd64.s

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,23 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$0
364364
POP_REGS_HOST_TO_ABI0()
365365
RET
366366

367+
// Called using C ABI.
368+
TEXT runtime·sigprofNonGoWrapper<>(SB),NOSPLIT,$0
369+
// Transition from C ABI to Go ABI.
370+
PUSH_REGS_HOST_TO_ABI0()
371+
372+
// Call into the Go signal handler
373+
NOP SP // disable vet stack checking
374+
ADJSP $24
375+
MOVL DI, 0(SP) // sig
376+
MOVQ SI, 8(SP) // info
377+
MOVQ DX, 16(SP) // ctx
378+
CALL ·sigprofNonGo(SB)
379+
ADJSP $-24
380+
381+
POP_REGS_HOST_TO_ABI0()
382+
RET
383+
367384
// Used instead of sigtramp in programs that use cgo.
368385
// Arguments from kernel are in DI, SI, DX.
369386
TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0
@@ -431,12 +448,12 @@ sigtrampnog:
431448
JNZ sigtramp // Skip stack trace if already locked.
432449

433450
// Jump to the traceback function in runtime/cgo.
434-
// It will call back to sigprofNonGo, which will ignore the
435-
// arguments passed in registers.
451+
// It will call back to sigprofNonGo, via sigprofNonGoWrapper, to convert
452+
// the arguments to the Go calling convention.
436453
// First three arguments to traceback function are in registers already.
437454
MOVQ runtime·cgoTraceback(SB), CX
438455
MOVQ $runtime·sigprofCallers(SB), R8
439-
MOVQ $runtime·sigprofNonGo(SB), R9
456+
MOVQ $runtime·sigprofNonGoWrapper<>(SB), R9
440457
MOVQ _cgo_callers(SB), AX
441458
JMP AX
442459

src/runtime/sys_linux_ppc64x.s

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -743,6 +743,9 @@ TEXT cgoSigtramp<>(SB),NOSPLIT,$0
743743
TEXT runtime·sigprofNonGoWrapper<>(SB),NOSPLIT,$0
744744
// We're coming from C code, set up essential register, then call sigprofNonGo.
745745
CALL runtime·reginit(SB)
746+
MOVW R3, FIXED_FRAME+0(R1) // sig
747+
MOVD R4, FIXED_FRAME+8(R1) // info
748+
MOVD R5, FIXED_FRAME+16(R1) // ctx
746749
CALL runtime·sigprofNonGo(SB)
747750
RET
748751

0 commit comments

Comments
 (0)