diff --git a/src/runtime/mgcmark.go b/src/runtime/mgcmark.go index 5d3a9efbb3..4a3cc4d769 100644 --- a/src/runtime/mgcmark.go +++ b/src/runtime/mgcmark.go @@ -522,45 +522,16 @@ func greyobject(obj, base, off uintptr, hbits heapBits, gcw *gcWorkProducer) { if useCheckmark { if !hbits.isMarked() { + printlock() print("runtime:greyobject: checkmarks finds unexpected unmarked object obj=", hex(obj), "\n") print("runtime: found obj at *(", hex(base), "+", hex(off), ")\n") // Dump the source (base) object - - kb := base >> _PageShift - xb := kb - xb -= mheap_.arena_start >> _PageShift - sb := h_spans[xb] - printlock() - print("runtime:greyobject Span: base=", hex(base), " kb=", hex(kb)) - if sb == nil { - print(" sb=nil\n") - } else { - print(" sb.start*_PageSize=", hex(sb.start*_PageSize), " sb.limit=", hex(sb.limit), " sb.sizeclass=", sb.sizeclass, " sb.elemsize=", sb.elemsize, "\n") - // base is (a pointer to) the source object holding the reference to object. Create a pointer to each of the fields - // fields in base and print them out as hex values. - for i := 0; i < int(sb.elemsize/ptrSize); i++ { - print(" *(base+", i*ptrSize, ") = ", hex(*(*uintptr)(unsafe.Pointer(base + uintptr(i)*ptrSize))), "\n") - } - } + gcDumpObject("base", base, off) // Dump the object + gcDumpObject("obj", obj, ^uintptr(0)) - k := obj >> _PageShift - x := k - x -= mheap_.arena_start >> _PageShift - s := h_spans[x] - print("runtime:greyobject Span: obj=", hex(obj), " k=", hex(k)) - if s == nil { - print(" s=nil\n") - } else { - print(" s.start=", hex(s.start*_PageSize), " s.limit=", hex(s.limit), " s.sizeclass=", s.sizeclass, " s.elemsize=", s.elemsize, "\n") - // NOTE(rsc): This code is using s.sizeclass as an approximation of the - // number of pointer-sized words in an object. Perhaps not what was intended. - for i := 0; i < int(s.sizeclass); i++ { - print(" *(obj+", i*ptrSize, ") = ", hex(*(*uintptr)(unsafe.Pointer(obj + uintptr(i)*ptrSize))), "\n") - } - } throw("checkmark found unmarked object") } if !hbits.isCheckmarked() { @@ -595,6 +566,28 @@ func greyobject(obj, base, off uintptr, hbits heapBits, gcw *gcWorkProducer) { gcw.put(obj) } +// gcDumpObject dumps the contents of obj for debugging and marks the +// field at byte offset off in obj. +func gcDumpObject(label string, obj, off uintptr) { + k := obj >> _PageShift + x := k + x -= mheap_.arena_start >> _PageShift + s := h_spans[x] + print(label, "=", hex(obj), " k=", hex(k)) + if s == nil { + print(" s=nil\n") + return + } + print(" s.start*_PageSize=", hex(s.start*_PageSize), " s.limit=", hex(s.limit), " s.sizeclass=", s.sizeclass, " s.elemsize=", s.elemsize, "\n") + for i := uintptr(0); i < s.elemsize; i += ptrSize { + print(" *(", label, "+", i, ") = ", hex(*(*uintptr)(unsafe.Pointer(obj + uintptr(i))))) + if i == off { + print(" <==") + } + print("\n") + } +} + // When in GCmarkterminate phase we allocate black. //go:nowritebarrier func gcmarknewobject_m(obj uintptr) {