diff options
author | Russ Cox <rsc@golang.org> | 2011-07-28 21:03:40 -0400 |
---|---|---|
committer | Russ Cox <rsc@golang.org> | 2011-07-28 21:03:40 -0400 |
commit | bed7e3ed78692b06128194abff79bd8c75731c88 (patch) | |
tree | 2103890824b44d583a6565bad6a0eaf58952ef77 | |
parent | 032ffb2e90b71b340684fe2b75abbd23f04352f1 (diff) | |
download | go-bed7e3ed78692b06128194abff79bd8c75731c88.tar.gz go-bed7e3ed78692b06128194abff79bd8c75731c88.zip |
gc: fix pprof deadlock
Fixes #2051.
R=golang-dev, dsymonds
CC=golang-dev
https://golang.org/cl/4834041
-rw-r--r-- | src/pkg/runtime/cpuprof.c | 4 | ||||
-rw-r--r-- | src/pkg/runtime/symtab.c | 17 |
2 files changed, 17 insertions, 4 deletions
diff --git a/src/pkg/runtime/cpuprof.c b/src/pkg/runtime/cpuprof.c index 6233bcb457..74b795b7ee 100644 --- a/src/pkg/runtime/cpuprof.c +++ b/src/pkg/runtime/cpuprof.c @@ -121,6 +121,10 @@ runtime·SetCPUProfileRate(int32 hz) { uintptr *p; uintptr n; + + // Call findfunc now so that it won't have to + // build tables during the signal handler. + runtime·findfunc(0); // Clamp hz to something reasonable. if(hz < 0) diff --git a/src/pkg/runtime/symtab.c b/src/pkg/runtime/symtab.c index ffa042e6f7..63e6d87849 100644 --- a/src/pkg/runtime/symtab.c +++ b/src/pkg/runtime/symtab.c @@ -420,10 +420,19 @@ runtime·findfunc(uintptr addr) Func *f; int32 nf, n; - runtime·lock(&funclock); - if(func == nil) - buildfuncs(); - runtime·unlock(&funclock); + // Use atomic double-checked locking, + // because when called from pprof signal + // handler, findfunc must run without + // grabbing any locks. + // (Before enabling the signal handler, + // SetCPUProfileRate calls findfunc to trigger + // the initialization outside the handler.) + if(runtime·atomicloadp(&func) == nil) { + runtime·lock(&funclock); + if(func == nil) + buildfuncs(); + runtime·unlock(&funclock); + } if(nfunc == 0) return nil; |