diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2015-01-26 21:44:06 +0300 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2015-01-27 17:26:36 +0000 |
| commit | 561ce92fa060f746a58c7301138f145632e79294 (patch) | |
| tree | a45a8988f9fcee30f28a80c9984e456b600dd4dd /src/runtime | |
| parent | 35b8e511c282a4d03f50dca0570a5f65795926b9 (diff) | |
| download | go-561ce92fa060f746a58c7301138f145632e79294.tar.xz | |
runtime: fix crash during heapdump
runtime/debug test crashes with GOMAXPROCS>1:
fatal error: unexpected signal during runtime execution
[signal 0xb code=0x1 addr=0x0 pc=0x80521b8]
runtime stack:
runtime.throw(0x8195028, 0x2a)
src/runtime/panic.go:508 +0x71 fp=0x18427f24 sp=0x18427f18
runtime.sigpanic()
src/runtime/sigpanic_unix.go:12 +0x53 fp=0x18427f4c sp=0x18427f24
runtime.finq_callback(0x0, 0x0, 0x0, 0x8129140, 0x0)
src/runtime/heapdump.go:410 +0x58 fp=0x18427f58 sp=0x18427f4c
runtime.iterate_finq(0x81a6860)
src/runtime/mfinal.go:89 +0x73 fp=0x18427f78 sp=0x18427f58
runtime.dumproots()
src/runtime/heapdump.go:448 +0x17a fp=0x18427fa4 sp=0x18427f78
runtime.mdump()
src/runtime/heapdump.go:652 +0xbc fp=0x18427fb4 sp=0x18427fa4
runtime.writeheapdump_m(0x3)
This happens because runfinq goroutine nils some elements in allfin after
execution of finalizers:
// drop finalizer queue references to finalized object
f.fn = nil
f.arg = nil
f.ot = nil
Then heapdump crashes trying to dereference fn.fn here:
func finq_callback(fn *funcval, obj unsafe.Pointer, nret uintptr, fint *_type, ot *ptrtype) {
dumpint(tagQueuedFinalizer)
dumpint(uint64(uintptr(obj)))
dumpint(uint64(uintptr(unsafe.Pointer(fn))))
dumpint(uint64(uintptr(unsafe.Pointer(fn.fn))))
dumpint(uint64(uintptr(unsafe.Pointer(fint))))
dumpint(uint64(uintptr(unsafe.Pointer(ot))))
}
Change-Id: I372433c964180d782967be63d4355e568666980d
Reviewed-on: https://go-review.googlesource.com/3287
Reviewed-by: Keith Randall <khr@golang.org>
Diffstat (limited to 'src/runtime')
| -rw-r--r-- | src/runtime/mfinal.go | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/src/runtime/mfinal.go b/src/runtime/mfinal.go index a9a4599166..3cc9a4e4c3 100644 --- a/src/runtime/mfinal.go +++ b/src/runtime/mfinal.go @@ -136,8 +136,8 @@ func runfinq() { racefingo() } for fb != nil { - for i := int32(0); i < fb.cnt; i++ { - f := (*finalizer)(add(unsafe.Pointer(&fb.fin), uintptr(i)*unsafe.Sizeof(finalizer{}))) + for i := fb.cnt; i > 0; i-- { + f := (*finalizer)(add(unsafe.Pointer(&fb.fin), uintptr(i-1)*unsafe.Sizeof(finalizer{}))) framesz := unsafe.Sizeof((interface{})(nil)) + uintptr(f.nret) if framecap < framesz { @@ -175,8 +175,8 @@ func runfinq() { f.fn = nil f.arg = nil f.ot = nil + fb.cnt = i - 1 } - fb.cnt = 0 next := fb.next lock(&finlock) fb.next = finc |
