| // Copyright 2019 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. |
| |
| // Make sure tracebacks from initialization code are reported correctly. |
| |
| package a |
| |
| import ( |
| "fmt" |
| "runtime" |
| "strings" |
| ) |
| |
| var x = f() // line 15 |
| |
| func f() int { |
| var b [4096]byte |
| n := runtime.Stack(b[:], false) // line 19 |
| s := string(b[:n]) |
| var pcs [10]uintptr |
| n = runtime.Callers(1, pcs[:]) // line 22 |
| |
| // Check the Stack results. |
| if debug { |
| println(s) |
| } |
| if strings.Contains(s, "autogenerated") { |
| panic("autogenerated code in traceback") |
| } |
| if !strings.Contains(s, "a.go:15") { |
| panic("missing a.go:15") |
| } |
| if !strings.Contains(s, "a.go:19") { |
| panic("missing a.go:19") |
| } |
| if !strings.Contains(s, "a.init") { |
| panic("missing a.init") |
| } |
| |
| // Check the CallersFrames results. |
| if debug { |
| iter := runtime.CallersFrames(pcs[:n]) |
| for { |
| f, more := iter.Next() |
| fmt.Printf("%s %s:%d\n", f.Function, f.File, f.Line) |
| if !more { |
| break |
| } |
| } |
| } |
| iter := runtime.CallersFrames(pcs[:n]) |
| f, more := iter.Next() |
| if f.Function != "test/a.f" || !strings.HasSuffix(f.File, "a.go") || f.Line != 22 { |
| panic(fmt.Sprintf("bad f %v\n", f)) |
| } |
| if !more { |
| panic("traceback truncated after f") |
| } |
| f, more = iter.Next() |
| if f.Function != "test/a.init" || !strings.HasSuffix(f.File, "a.go") || f.Line != 15 { |
| panic(fmt.Sprintf("bad init %v\n", f)) |
| } |
| if !more { |
| panic("traceback truncated after init") |
| } |
| f, _ = iter.Next() |
| if !strings.HasPrefix(f.Function, "runtime.") { |
| panic("runtime. driver missing") |
| } |
| |
| return 0 |
| } |
| |
| const debug = false |