]> Cypherpunks repositories - gostls13.git/commitdiff
gc: fix pprof deadlock
authorRuss Cox <rsc@golang.org>
Fri, 29 Jul 2011 01:03:40 +0000 (21:03 -0400)
committerRuss Cox <rsc@golang.org>
Fri, 29 Jul 2011 01:03:40 +0000 (21:03 -0400)
Fixes #2051.

R=golang-dev, dsymonds
CC=golang-dev
https://golang.org/cl/4834041

src/pkg/runtime/cpuprof.c
src/pkg/runtime/symtab.c

index 6233bcb45703c8935635d2727c32cd06f8d5a7b4..74b795b7ee2bcfd525fd372b7fca121e0ad75c17 100644 (file)
@@ -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)
index ffa042e6f729ea52d07c9bf2146c7857f2677196..63e6d87849f21ba64f4859303c68f210da897fee 100644 (file)
@@ -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;