1// run 2 3// Copyright 2016 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// issue 17381: make sure leave function with non-empty frame 8// saves link register, so that traceback will work. 9 10package main 11 12import ( 13 "runtime" 14 "unsafe" 15) 16 17func main() { 18 defer func() { 19 if recover() == nil { 20 panic("did not panic") 21 } 22 pcs := make([]uintptr, 20) 23 n := runtime.Callers(1, pcs) 24 for _, pc := range pcs[:n] { 25 if runtime.FuncForPC(pc).Name() == "main.main" { 26 return 27 } 28 } 29 panic("cannot find main.main in backtrace") 30 }() 31 32 prep() 33 f() // should panic 34} 35 36func funcPC(f interface{}) uintptr { 37 var ptr uintptr 38 return **(**uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(&f)) + unsafe.Sizeof(ptr))) 39} 40 41//go:noinline 42func f() { 43 var t [1]int // non-empty frame 44 *(*int)(nil) = t[0] 45} 46 47var p = funcPC(runtime.GC) + 8 48 49//go:noinline 50func prep() { 51 // put some garbage on stack 52 var x = [20]uintptr{p, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p} 53 _ = x 54} 55