1// run 2 3// Copyright 2018 The Go Authors. All rights reserved. 4// Use of this source code is governed by a BSD-style 5// license that can be found in the LICENSE file. 6 7package main 8 9import ( 10 "runtime" 11) 12 13var nilp *int 14var forceHeap interface{} 15 16func main() { 17 // x is a pointer on the stack to heap-allocated memory. 18 x := new([32]*int) 19 forceHeap = x 20 forceHeap = nil 21 22 // Push a defer to be run when we panic below. 23 defer func() { 24 // Ignore the panic. 25 recover() 26 // Force a stack walk. Go 1.11 will fail because x is now 27 // considered live again. 28 runtime.GC() 29 }() 30 // Make x live at the defer's PC. 31 runtime.KeepAlive(x) 32 33 // x is no longer live. Garbage collect the [32]*int on the 34 // heap. 35 runtime.GC() 36 // At this point x's dead stack slot points to dead memory. 37 38 // Trigger a sigpanic. Since this is an implicit panic, we 39 // don't have an explicit liveness map here. 40 // Traceback used to use the liveness map of the most recent defer, 41 // but in that liveness map, x will be live again even though 42 // it points to dead memory. The fix is to use the liveness 43 // map of a deferreturn call instead. 44 *nilp = 0 45} 46