mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
runtime: enable/disable SIGPROF if needed when profiling
This ensures that SIGPROF is handled correctly when using runtime/pprof in a c-archive or c-shared library. Separate profiler handling into pre-process changes and per-thread changes. Simplify the Windows code slightly accordingly. Fixes #18220. Change-Id: I5060f7084c91ef0bbe797848978bdc527c312777 Reviewed-on: https://go-review.googlesource.com/34018 TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Austin Clements <austin@google.com> Run-TryBot: Austin Clements <austin@google.com>
This commit is contained in:
parent
6a29806e01
commit
e24228af25
8 changed files with 152 additions and 14 deletions
|
|
@ -138,6 +138,11 @@ func sigenable(sig uint32) {
|
|||
return
|
||||
}
|
||||
|
||||
// SIGPROF is handled specially for profiling.
|
||||
if sig == _SIGPROF {
|
||||
return
|
||||
}
|
||||
|
||||
t := &sigtable[sig]
|
||||
if t.flags&_SigNotify != 0 {
|
||||
ensureSigM()
|
||||
|
|
@ -158,6 +163,11 @@ func sigdisable(sig uint32) {
|
|||
return
|
||||
}
|
||||
|
||||
// SIGPROF is handled specially for profiling.
|
||||
if sig == _SIGPROF {
|
||||
return
|
||||
}
|
||||
|
||||
t := &sigtable[sig]
|
||||
if t.flags&_SigNotify != 0 {
|
||||
ensureSigM()
|
||||
|
|
@ -182,6 +192,11 @@ func sigignore(sig uint32) {
|
|||
return
|
||||
}
|
||||
|
||||
// SIGPROF is handled specially for profiling.
|
||||
if sig == _SIGPROF {
|
||||
return
|
||||
}
|
||||
|
||||
t := &sigtable[sig]
|
||||
if t.flags&_SigNotify != 0 {
|
||||
atomic.Store(&handlingSig[sig], 0)
|
||||
|
|
@ -189,7 +204,31 @@ func sigignore(sig uint32) {
|
|||
}
|
||||
}
|
||||
|
||||
func resetcpuprofiler(hz int32) {
|
||||
// setProcessCPUProfiler is called when the profiling timer changes.
|
||||
// It is called with prof.lock held. hz is the new timer, and is 0 if
|
||||
// profiling is being disabled. Enable or disable the signal as
|
||||
// required for -buildmode=c-archive.
|
||||
func setProcessCPUProfiler(hz int32) {
|
||||
if hz != 0 {
|
||||
// Enable the Go signal handler if not enabled.
|
||||
if atomic.Cas(&handlingSig[_SIGPROF], 0, 1) {
|
||||
atomic.Storeuintptr(&fwdSig[_SIGPROF], getsig(_SIGPROF))
|
||||
setsig(_SIGPROF, funcPC(sighandler))
|
||||
}
|
||||
} else {
|
||||
// If the Go signal handler should be disabled by default,
|
||||
// disable it if it is enabled.
|
||||
if !sigInstallGoHandler(_SIGPROF) {
|
||||
if atomic.Cas(&handlingSig[_SIGPROF], 1, 0) {
|
||||
setsig(_SIGPROF, atomic.Loaduintptr(&fwdSig[_SIGPROF]))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// setThreadCPUProfiler makes any thread-specific changes required to
|
||||
// implement profiling at a rate of hz.
|
||||
func setThreadCPUProfiler(hz int32) {
|
||||
var it itimerval
|
||||
if hz == 0 {
|
||||
setitimer(_ITIMER_PROF, &it, nil)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue