mirror of
https://github.com/golang/go
synced 2024-11-02 08:01:26 +00:00
runtime: record extra information in throwOnGCWork crashes
Currently we only know the slot address and the value being written in the throwOnGCWork crash tracebacks, and we have to infer the old value from what's dumped by gcWork.checkPut. Sometimes these old values don't make sense, like when we see a write of a nil pointer to a freshly-allocated object, yet we observe marking a value (where did that pointer come from?). This CL adds the old value of the slot and the first two pointers in the buffer to the traceback. For #27993. Change-Id: Ib70eead1afb9c06e8099e520172c3a2acaa45f80 Reviewed-on: https://go-review.googlesource.com/c/154597 Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Michael Knyszek <mknyszek@google.com>
This commit is contained in:
parent
503091a77c
commit
3c255e8bc6
1 changed files with 23 additions and 1 deletions
|
@ -197,10 +197,32 @@ func wbBufFlush(dst *uintptr, src uintptr) {
|
|||
// Switch to the system stack so we don't have to worry about
|
||||
// the untyped stack slots or safe points.
|
||||
systemstack(func() {
|
||||
wbBufFlush1(getg().m.p.ptr())
|
||||
if debugCachedWork {
|
||||
// For debugging, include the old value of the
|
||||
// slot and some other data in the traceback.
|
||||
wbBuf := &getg().m.p.ptr().wbBuf
|
||||
var old uintptr
|
||||
if dst != nil {
|
||||
// dst may be nil in direct calls to wbBufFlush.
|
||||
old = *dst
|
||||
}
|
||||
wbBufFlush1Debug(old, wbBuf.buf[0], wbBuf.buf[1], &wbBuf.buf[0], wbBuf.next)
|
||||
} else {
|
||||
wbBufFlush1(getg().m.p.ptr())
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// wbBufFlush1Debug is a temporary function for debugging issue
|
||||
// #27993. It exists solely to add some context to the traceback.
|
||||
//
|
||||
//go:nowritebarrierrec
|
||||
//go:systemstack
|
||||
//go:noinline
|
||||
func wbBufFlush1Debug(old, buf1, buf2 uintptr, start *uintptr, next uintptr) {
|
||||
wbBufFlush1(getg().m.p.ptr())
|
||||
}
|
||||
|
||||
// wbBufFlush1 flushes p's write barrier buffer to the GC work queue.
|
||||
//
|
||||
// This must not have write barriers because it is part of the write
|
||||
|
|
Loading…
Reference in a new issue