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>
This commit is contained in:
Cherry Zhang 2019-02-09 23:31:59 -05:00
parent ffd096db2b
commit af8f4062c2
6 changed files with 58 additions and 1 deletions

View file

@ -728,3 +728,15 @@ func TestG0StackOverflow(t *testing.T) {
runtime.G0StackOverflow()
}
// Test that panic message is not clobbered.
// See issue 30150.
func TestDoublePanic(t *testing.T) {
output := runTestProg(t, "testprog", "DoublePanic", "GODEBUG=clobberfree=1")
wants := []string{"panic: XXX", "panic: YYY"}
for _, want := range wants {
if !strings.Contains(output, want) {
t.Errorf("output:\n%s\n\nwant output containing: %s", output, want)
}
}
}