11 // Frame represents a program counter inside a stack frame.
14 // pc returns the program counter for this frame;
15 // multiple frames may have the same PC value.
16 func (f Frame) pc() uintptr { return uintptr(f) - 1 }
18 // file returns the full path to the file that contains the
19 // function for this Frame's pc.
20 func (f Frame) file() string {
21 fn := runtime.FuncForPC(f.pc())
25 file, _ := fn.FileLine(f.pc())
29 // line returns the line number of source code of the
30 // function for this Frame's pc.
31 func (f Frame) line() int {
32 fn := runtime.FuncForPC(f.pc())
36 _, line := fn.FileLine(f.pc())
40 // Format formats the frame according to the fmt.Formatter interface.
45 // %v equivalent to %s:%d
47 // Format accepts flags that alter the printing of some verbs, as follows:
49 // %+s function name and path of source file relative to the compile time
50 // GOPATH separated by \n\t (<funcname>\n\t<path>)
51 // %+v equivalent to %+s:%d
52 func (f Frame) Format(s fmt.State, verb rune) {
58 fn := runtime.FuncForPC(pc)
60 io.WriteString(s, "unknown")
62 file, _ := fn.FileLine(pc)
63 fmt.Fprintf(s, "%s\n\t%s", fn.Name(), file)
66 io.WriteString(s, path.Base(f.file()))
69 fmt.Fprintf(s, "%d", f.line())
71 name := runtime.FuncForPC(f.pc()).Name()
72 io.WriteString(s, funcname(name))
75 io.WriteString(s, ":")
80 // StackTrace is stack of Frames from innermost (newest) to outermost (oldest).
81 type StackTrace []Frame
83 // Format formats the stack of Frames according to the fmt.Formatter interface.
85 // %s lists source files for each Frame in the stack
86 // %v lists the source file and line number for each Frame in the stack
88 // Format accepts flags that alter the printing of some verbs, as follows:
90 // %+v Prints filename, function, and line number for each Frame in the stack.
91 func (st StackTrace) Format(s fmt.State, verb rune) {
96 for _, f := range st {
97 fmt.Fprintf(s, "\n%+v", f)
100 fmt.Fprintf(s, "%#v", []Frame(st))
102 fmt.Fprintf(s, "%v", []Frame(st))
105 fmt.Fprintf(s, "%s", []Frame(st))
109 // stack represents a stack of program counters.
112 func (s *stack) Format(st fmt.State, verb rune) {
117 for _, pc := range *s {
119 fmt.Fprintf(st, "\n%+v", f)
125 func (s *stack) StackTrace() StackTrace {
126 f := make([]Frame, len(*s))
127 for i := 0; i < len(f); i++ {
128 f[i] = Frame((*s)[i])
133 func callers() *stack {
135 var pcs [depth]uintptr
136 n := runtime.Callers(3, pcs[:])
137 var st stack = pcs[0:n]
141 // funcname removes the path prefix component of a function's name reported by func.Name().
142 func funcname(name string) string {
143 i := strings.LastIndex(name, "/")
145 i = strings.Index(name, ".")