runtime: print pointers being put in checkPut

In order to further diagnose #27993, I need to see exactly what
pointers are being added to the gcWork buffer too late.

Change-Id: I8d92113426ffbc6e55d819c39e7ab5eafa68668d
Reviewed-on: https://go-review.googlesource.com/c/152957
Run-TryBot: Austin Clements <austin@google.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
diff --git a/src/runtime/mgcwork.go b/src/runtime/mgcwork.go
index 8a77ff5..cdc94b8 100644
--- a/src/runtime/mgcwork.go
+++ b/src/runtime/mgcwork.go
@@ -115,11 +115,19 @@
 	w.wbuf2 = wbuf2
 }
 
-func (w *gcWork) checkPut() {
+func (w *gcWork) checkPut(ptr uintptr, ptrs []uintptr) {
 	if debugCachedWork {
 		for atomic.Load(&gcWorkPauseGen) == w.pauseGen {
 		}
 		if throwOnGCWork {
+			printlock()
+			println("runtime: late gcWork put")
+			if ptr != 0 {
+				gcDumpObject("ptr", ptr, ^uintptr(0))
+			}
+			for _, ptr := range ptrs {
+				gcDumpObject("ptrs", ptr, ^uintptr(0))
+			}
 			throw("throwOnGCWork")
 		}
 	}
@@ -129,7 +137,7 @@
 // obj must point to the beginning of a heap object or an oblet.
 //go:nowritebarrierrec
 func (w *gcWork) put(obj uintptr) {
-	w.checkPut()
+	w.checkPut(obj, nil)
 
 	flushed := false
 	wbuf := w.wbuf1
@@ -165,7 +173,7 @@
 // otherwise it returns false and the caller needs to call put.
 //go:nowritebarrierrec
 func (w *gcWork) putFast(obj uintptr) bool {
-	w.checkPut()
+	w.checkPut(obj, nil)
 
 	wbuf := w.wbuf1
 	if wbuf == nil {
@@ -188,7 +196,7 @@
 		return
 	}
 
-	w.checkPut()
+	w.checkPut(0, obj)
 
 	flushed := false
 	wbuf := w.wbuf1
@@ -311,12 +319,12 @@
 		return
 	}
 	if wbuf := w.wbuf2; wbuf.nobj != 0 {
-		w.checkPut()
+		w.checkPut(0, wbuf.obj[:wbuf.nobj])
 		putfull(wbuf)
 		w.flushedWork = true
 		w.wbuf2 = getempty()
 	} else if wbuf := w.wbuf1; wbuf.nobj > 4 {
-		w.checkPut()
+		w.checkPut(0, wbuf.obj[:wbuf.nobj])
 		w.wbuf1 = handoff(wbuf)
 		w.flushedWork = true // handoff did putfull
 	} else {