aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2011-07-28 21:03:40 -0400
committerRuss Cox <rsc@golang.org>2011-07-28 21:03:40 -0400
commitbed7e3ed78692b06128194abff79bd8c75731c88 (patch)
tree2103890824b44d583a6565bad6a0eaf58952ef77
parent032ffb2e90b71b340684fe2b75abbd23f04352f1 (diff)
downloadgo-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.c4
-rw-r--r--src/pkg/runtime/symtab.c17
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;