This change dumps a scan trace (each pointer marked and where it came
from) for the partial GC cycle performed by checkfinalizers mode when
checkfinalizers>1. This is useful for quickly understanding why certain
values are reachable without having to pull out tools like viewcore.
For #72949.
Change-Id: Ic583f80e9558cdfe1c667d27a1d975008dd39a9c
Reviewed-on: https://go-review.googlesource.com/c/go/+/662038
Reviewed-by: Michael Pratt <mpratt@google.com>
Reviewed-by: Carlos Amedee <carlos@golang.org>
Auto-Submit: Michael Knyszek <mknyszek@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
}
// Run a checkmark GC using this cleanup and/or finalizer as a root.
+ if debug.checkfinalizers > 1 {
+ print("Scan trace for cleanup/finalizer on ", hex(p), ":\n")
+ }
runCheckmark(func(gcw *gcWork) {
switch sp.kind {
case _KindSpecialFinalizer:
gcScanCleanup((*specialCleanup)(unsafe.Pointer(sp)), gcw)
}
})
+ if debug.checkfinalizers > 1 {
+ println()
+ }
// Now check to see if the object the special is attached to was marked.
// The roots above do not directly mark p, so if it is marked, then p
// Already marked.
return
}
+ if debug.checkfinalizers > 1 {
+ print(" mark ", hex(obj), " found at *(", hex(base), "+", hex(off), ")\n")
+ }
} else {
if debug.gccheckmark > 0 && span.isFree(objIndex) {
print("runtime: marking free object ", hex(obj), " found at *(", hex(base), "+", hex(off), ")\n")