mirror of
https://github.com/golang/go
synced 2024-11-11 20:50:23 -07:00
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>
This commit is contained in:
parent
35b8e511c2
commit
561ce92fa0
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user