1// run 2 3// Copyright 2019 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 7// Make sure we use the deferreturn live map instead of 8// the entry live map when handling a segv in a function 9// that defers. 10 11package main 12 13import "runtime" 14 15var finalized bool 16var err string 17 18type HeapObj [8]int64 19 20const filler int64 = 0x123456789abcdef0 21 22func (h *HeapObj) init() { 23 for i := 0; i < len(*h); i++ { 24 h[i] = filler 25 } 26} 27func (h *HeapObj) check() { 28 for i := 0; i < len(*h); i++ { 29 if h[i] != filler { 30 err = "filler overwritten" 31 } 32 } 33} 34 35func gc(shouldFinalize bool) { 36 runtime.GC() 37 runtime.GC() 38 runtime.GC() 39 if shouldFinalize != finalized { 40 err = "heap object finalized at the wrong time" 41 } 42} 43 44func main() { 45 h := new(HeapObj) 46 h.init() 47 runtime.SetFinalizer(h, func(h *HeapObj) { 48 finalized = true 49 }) 50 51 gc(false) 52 g(h) 53 if err != "" { 54 panic(err) 55 } 56} 57 58func g(h *HeapObj) { 59 gc(false) 60 h.check() 61 // h is now unused 62 defer func() { 63 // h should not be live here. Previously we used to 64 // use the function entry point as the place to get 65 // the live map when handling a segv. 66 gc(true) 67 recover() 68 }() 69 *(*int)(nil) = 0 // trigger a segv 70 return 71} 72