]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: fix crash during cpu profiling
authorDmitriy Vyukov <dvyukov@google.com>
Mon, 10 Feb 2014 16:24:47 +0000 (20:24 +0400)
committerDmitriy Vyukov <dvyukov@google.com>
Mon, 10 Feb 2014 16:24:47 +0000 (20:24 +0400)
mp->mcache can be concurrently modified by runtime·helpgc.
In such case sigprof can remember mcache=nil, then helpgc sets it to non-nil,
then sigprof restores it back to nil, GC crashes with nil mcache.

R=rsc
CC=golang-codereviews
https://golang.org/cl/58860044

src/pkg/runtime/proc.c

index 52aee39ca334332dacbd8840904c93e4ff54427d..c771d5f916a5b99161f181c6388c94f0788ad441 100644 (file)
@@ -2115,7 +2115,6 @@ runtime·sigprof(uint8 *pc, uint8 *sp, uint8 *lr, G *gp, M *mp)
 {
        int32 n;
        bool traceback;
-       MCache *mcache;
        // Do not use global m in this function, use mp instead.
        // On windows one m is sending reports about all the g's, so m means a wrong thing.
        byte m;
@@ -2127,8 +2126,7 @@ runtime·sigprof(uint8 *pc, uint8 *sp, uint8 *lr, G *gp, M *mp)
                return;
 
        // Profiling runs concurrently with GC, so it must not allocate.
-       mcache = mp->mcache;
-       mp->mcache = nil;
+       mp->mallocing++;
 
        // Define that a "user g" is a user-created goroutine, and a "system g"
        // is one that is m->g0 or m->gsignal. We've only made sure that we
@@ -2216,7 +2214,7 @@ runtime·sigprof(uint8 *pc, uint8 *sp, uint8 *lr, G *gp, M *mp)
        runtime·lock(&prof);
        if(prof.fn == nil) {
                runtime·unlock(&prof);
-               mp->mcache = mcache;
+               mp->mallocing--;
                return;
        }
        n = 0;
@@ -2229,7 +2227,7 @@ runtime·sigprof(uint8 *pc, uint8 *sp, uint8 *lr, G *gp, M *mp)
        }
        prof.fn(prof.pcbuf, n);
        runtime·unlock(&prof);
-       mp->mcache = mcache;
+       mp->mallocing--;
 }
 
 // Arrange to call fn with a traceback hz times a second.