1// Copyright 2019 The Go Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style 3// license that can be found in the LICENSE file. 4 5// Make sure tracebacks from initialization code are reported correctly. 6 7package a 8 9import ( 10 "fmt" 11 "runtime" 12 "strings" 13) 14 15var x = f() // line 15 16 17func f() int { 18 var b [4096]byte 19 n := runtime.Stack(b[:], false) // line 19 20 s := string(b[:n]) 21 var pcs [10]uintptr 22 n = runtime.Callers(1, pcs[:]) // line 22 23 24 // Check the Stack results. 25 if debug { 26 println(s) 27 } 28 if strings.Contains(s, "autogenerated") { 29 panic("autogenerated code in traceback") 30 } 31 if !strings.Contains(s, "a.go:15") { 32 panic("missing a.go:15") 33 } 34 if !strings.Contains(s, "a.go:19") { 35 panic("missing a.go:19") 36 } 37 if !strings.Contains(s, "a.init") { 38 panic("missing a.init") 39 } 40 41 // Check the CallersFrames results. 42 if debug { 43 iter := runtime.CallersFrames(pcs[:n]) 44 for { 45 f, more := iter.Next() 46 fmt.Printf("%s %s:%d\n", f.Function, f.File, f.Line) 47 if !more { 48 break 49 } 50 } 51 } 52 iter := runtime.CallersFrames(pcs[:n]) 53 f, more := iter.Next() 54 if f.Function != "test/a.f" || !strings.HasSuffix(f.File, "a.go") || f.Line != 22 { 55 panic(fmt.Sprintf("bad f %v\n", f)) 56 } 57 if !more { 58 panic("traceback truncated after f") 59 } 60 f, more = iter.Next() 61 if f.Function != "test/a.init" || !strings.HasSuffix(f.File, "a.go") || f.Line != 15 { 62 panic(fmt.Sprintf("bad init %v\n", f)) 63 } 64 if !more { 65 panic("traceback truncated after init") 66 } 67 f, _ = iter.Next() 68 if !strings.HasPrefix(f.Function, "runtime.") { 69 panic("runtime. driver missing") 70 } 71 72 return 0 73} 74 75const debug = false 76