]> Cypherpunks repositories - gostls13.git/commitdiff
runtime/pprof: fix data race between Profile.Add and Profile.WriteTo
authorJosh Bleecher Snyder <josharian@gmail.com>
Thu, 2 Mar 2017 23:10:55 +0000 (15:10 -0800)
committerJosh Bleecher Snyder <josharian@gmail.com>
Thu, 2 Mar 2017 23:30:07 +0000 (23:30 +0000)
p.m is accessed in WriteTo without holding p.mu.
Move the access inside the critical section.

The race detector catches this bug using this program:

package main

import (
"os"
"runtime/pprof"
"time"
)

func main() {
p := pprof.NewProfile("ABC")
go func() {
p.WriteTo(os.Stdout, 1)
time.Sleep(time.Second)
}()
p.Add("abc", 0)
time.Sleep(time.Second)
}

$ go run -race x.go
==================
WARNING: DATA RACE
Write at 0x00c42007c240 by main goroutine:
  runtime.mapassign()
      /Users/josh/go/tip/src/runtime/hashmap.go:485 +0x0
  runtime/pprof.(*Profile).Add()
      /Users/josh/go/tip/src/runtime/pprof/pprof.go:281 +0x255
  main.main()
      /Users/josh/go/tip/src/p.go:15 +0x9d

Previous read at 0x00c42007c240 by goroutine 6:
  runtime/pprof.(*Profile).WriteTo()
      /Users/josh/go/tip/src/runtime/pprof/pprof.go:314 +0xc5
  main.main.func1()
      /Users/josh/go/tip/src/x.go:12 +0x69

Goroutine 6 (running) created at:
  main.main()
      /Users/josh/go/tip/src/x.go:11 +0x6e
==================
ABC profile: total 1
1 @ 0x110ccb4 0x111aeee 0x1055053 0x107f031

Found 1 data race(s)
exit status 66

(Exit status 66?)

Change-Id: I49d884dc3af9cce2209057a3448fe6bf50653523
Reviewed-on: https://go-review.googlesource.com/37730
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
src/runtime/pprof/pprof.go

index 4d1068d66523ca7803a0707cf02669fe7d5506cb..98c08654cf600550841082ff14a4e3e9a2d076be 100644 (file)
@@ -311,8 +311,8 @@ func (p *Profile) WriteTo(w io.Writer, debug int) error {
        }
 
        // Obtain consistent snapshot under lock; then process without lock.
-       all := make([][]uintptr, 0, len(p.m))
        p.mu.Lock()
+       all := make([][]uintptr, 0, len(p.m))
        for _, stk := range p.m {
                all = append(all, stk)
        }