aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/mgcmark.go
diff options
context:
space:
mode:
authorCherry Zhang <cherryyz@google.com>2019-02-09 23:31:59 -0500
committerCherry Zhang <cherryyz@google.com>2019-02-13 15:49:22 +0000
commitaf8f4062c24cb36af4dc24fbaffd23aa7f7bde36 (patch)
tree9b3c719fea5208f3acb4a402790f1c551247b09e /src/runtime/mgcmark.go
parentffd096db2b1cff6399eb1f86e5652564ee8ee362 (diff)
downloadgo-af8f4062c24cb36af4dc24fbaffd23aa7f7bde36.tar.gz
go-af8f4062c24cb36af4dc24fbaffd23aa7f7bde36.zip
runtime: scan gp._panic in stack scan
In runtime.gopanic, the _panic object p is stack allocated and referenced from gp._panic. With stack objects, p on stack is dead at the point preprintpanics runs. gp._panic points to p, but stack scan doesn't look at gp. Heap scan of gp does look at gp._panic, but it stops and ignores the pointer as it points to the stack. So whatever p points to may be collected and clobbered. We need to scan gp._panic explicitly during stack scan. To test it reliably, we introduce a GODEBUG mode "clobberfree", which clobbers the memory content when the GC frees an object. Fixes #30150. Change-Id: I11128298f03a89f817faa221421a9d332b41dced Reviewed-on: https://go-review.googlesource.com/c/161778 Run-TryBot: Cherry Zhang <cherryyz@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org> Reviewed-by: Austin Clements <austin@google.com>
Diffstat (limited to 'src/runtime/mgcmark.go')
-rw-r--r--src/runtime/mgcmark.go6
1 files changed, 6 insertions, 0 deletions
diff --git a/src/runtime/mgcmark.go b/src/runtime/mgcmark.go
index 86416caab5..022cc8d7d7 100644
--- a/src/runtime/mgcmark.go
+++ b/src/runtime/mgcmark.go
@@ -709,7 +709,13 @@ func scanstack(gp *g, gcw *gcWork) {
return true
}
gentraceback(^uintptr(0), ^uintptr(0), 0, gp, 0, nil, 0x7fffffff, scanframe, nil, 0)
+
+ // Find additional pointers that point into the stack from the heap.
+ // Currently this includes defers and panics. See also function copystack.
tracebackdefers(gp, scanframe, nil)
+ if gp._panic != nil {
+ state.putPtr(uintptr(unsafe.Pointer(gp._panic)))
+ }
// Find and scan all reachable stack objects.
state.buildIndex()