Skip to content

Commit bed7e3e

Browse files
committed
gc: fix pprof deadlock
Fixes #2051. R=golang-dev, dsymonds CC=golang-dev https://golang.org/cl/4834041
1 parent 032ffb2 commit bed7e3e

File tree

2 files changed

+17
-4
lines changed

2 files changed

+17
-4
lines changed

src/pkg/runtime/cpuprof.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,10 @@ runtime·SetCPUProfileRate(int32 hz)
121121
{
122122
uintptr *p;
123123
uintptr n;
124+
125+
// Call findfunc now so that it won't have to
126+
// build tables during the signal handler.
127+
runtime·findfunc(0);
124128

125129
// Clamp hz to something reasonable.
126130
if(hz < 0)

src/pkg/runtime/symtab.c

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -420,10 +420,19 @@ runtime·findfunc(uintptr addr)
420420
Func *f;
421421
int32 nf, n;
422422

423-
runtime·lock(&funclock);
424-
if(func == nil)
425-
buildfuncs();
426-
runtime·unlock(&funclock);
423+
// Use atomic double-checked locking,
424+
// because when called from pprof signal
425+
// handler, findfunc must run without
426+
// grabbing any locks.
427+
// (Before enabling the signal handler,
428+
// SetCPUProfileRate calls findfunc to trigger
429+
// the initialization outside the handler.)
430+
if(runtime·atomicloadp(&func) == nil) {
431+
runtime·lock(&funclock);
432+
if(func == nil)
433+
buildfuncs();
434+
runtime·unlock(&funclock);
435+
}
427436

428437
if(nfunc == 0)
429438
return nil;

0 commit comments

Comments
 (0)