// run // Copyright 2018 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package main import ( "runtime" ) var nilp *int var forceHeap interface{} func main() { // x is a pointer on the stack to heap-allocated memory. x := new([32]*int) forceHeap = x forceHeap = nil // Push a defer to be run when we panic below. defer func() { // Ignore the panic. recover() // Force a stack walk. Go 1.11 will fail because x is now // considered live again. runtime.GC() }() // Make x live at the defer's PC. runtime.KeepAlive(x) // x is no longer live. Garbage collect the [32]*int on the // heap. runtime.GC() // At this point x's dead stack slot points to dead memory. // Trigger a sigpanic. Since this is an implicit panic, we // don't have an explicit liveness map here. // Traceback used to use the liveness map of the most recent defer, // but in that liveness map, x will be live again even though // it points to dead memory. The fix is to use the liveness // map of a deferreturn call instead. *nilp = 0 }