diff options
author | Keith Randall <khr@golang.org> | 2014-12-15 14:39:28 -0800 |
---|---|---|
committer | Keith Randall <khr@golang.org> | 2014-12-16 17:04:45 +0000 |
commit | 50bc3d5bbc6710663c082aa72c8ba4f9ee515ab3 (patch) | |
tree | c6bd70290604d573c47db3a9370503704deb8557 /src/runtime/mprof.go | |
parent | 8f36655346396e32952c6a7c9cfbc16c73a1ff4d (diff) | |
download | go-50bc3d5bbc6710663c082aa72c8ba4f9ee515ab3.tar.gz go-50bc3d5bbc6710663c082aa72c8ba4f9ee515ab3.zip |
runtime: fix deadlock in runtime.Stack
It shouldn't semacquire() inside an acquirem(), the runtime
thinks that means deadlock. It actually isn't a deadlock, but it
looks like it because acquirem() does m.locks++.
Candidate for inclusion in 1.4.1. runtime.Stack with all=true
is pretty unuseable in GOMAXPROCS>1 environment.
fixes #9321
Change-Id: Iac6b664217d24763b9878c20e49229a1ecffc805
Reviewed-on: https://go-review.googlesource.com/1600
Reviewed-by: Dmitry Vyukov <dvyukov@google.com>
Diffstat (limited to 'src/runtime/mprof.go')
-rw-r--r-- | src/runtime/mprof.go | 14 |
1 files changed, 5 insertions, 9 deletions
diff --git a/src/runtime/mprof.go b/src/runtime/mprof.go index ba989b1b86..6435c0446a 100644 --- a/src/runtime/mprof.go +++ b/src/runtime/mprof.go @@ -564,20 +564,16 @@ func saveg(pc, sp uintptr, gp *g, r *StackRecord) { // If all is true, Stack formats stack traces of all other goroutines // into buf after the trace for the current goroutine. func Stack(buf []byte, all bool) int { - mp := acquirem() - gp := mp.curg if all { semacquire(&worldsema, false) - mp.gcing = 1 - releasem(mp) + gp := getg() + gp.m.gcing = 1 systemstack(stoptheworld) - if mp != acquirem() { - gothrow("Stack: rescheduled") - } } n := 0 if len(buf) > 0 { + gp := getg() sp := getcallersp(unsafe.Pointer(&buf)) pc := getcallerpc(unsafe.Pointer(&buf)) systemstack(func() { @@ -594,11 +590,11 @@ func Stack(buf []byte, all bool) int { } if all { - mp.gcing = 0 + gp := getg() + gp.m.gcing = 0 semrelease(&worldsema) systemstack(starttheworld) } - releasem(mp) return n } |