1 // Copyright 2014 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.
7 // Frames may be used to get function/file/line information for a
8 // slice of PC values returned by Callers.
10 // callers is a slice of PCs that have not yet been expanded.
13 // The last PC we saw.
16 // The number of times we've seen last.
20 // Frame is the information returned by Frames for each call frame.
22 // PC is the program counter for the location in this frame.
23 // For a frame that calls another frame, this will be the
24 // program counter of a call instruction. Because of inlining,
25 // multiple frames may have the same PC value, but different
26 // symbolic information.
29 // Func is the Func value of this call frame. This may be nil
30 // for non-Go code or fully inlined functions.
33 // Function is the package path-qualified function name of
34 // this call frame. If non-empty, this string uniquely
35 // identifies a single function in the program.
36 // This may be the empty string if not known.
37 // If Func is not nil then Function == Func.Name().
40 // File and Line are the file name and line number of the
41 // location in this frame. For non-leaf frames, this will be
42 // the location of a call. These may be the empty string and
43 // zero, respectively, if not known.
47 // Entry point program counter for the function; may be zero
48 // if not known. If Func is not nil then Entry ==
53 // CallersFrames takes a slice of PC values returned by Callers and
54 // prepares to return function/file/line information.
55 // Do not change the slice until you are done with the Frames.
56 func CallersFrames(callers
[]uintptr) *Frames
{
57 return &Frames
{callers
: callers
}
60 // Next returns frame information for the next caller.
61 // If more is false, there are no more callers (the Frame value is valid).
62 func (ci
*Frames
) Next() (frame Frame
, more
bool) {
63 if len(ci
.callers
) == 0 {
68 ci
.callers
= ci
.callers
[1:]
78 more
= len(ci
.callers
) > 0
80 // Subtract 1 from PC to undo the 1 we added in callback in
82 function
, file
, line
:= funcfileline(pc
-1, int32(i
))
83 if function
== "" && file
== "" {
86 entry
:= funcentry(pc
- 1)
87 f
:= &Func
{name
: function
, entry
: entry
}
106 // NOTE: Func does not expose the actual unexported fields, because we return *Func
107 // values to users, and we want to keep them from being able to overwrite the data
108 // with (say) *f = Func{}.
109 // All code operating on a *Func must call raw() to get the *_func
110 // or funcInfo() to get the funcInfo instead.
112 // A Func represents a Go function in the running binary.
118 // FuncForPC returns a *Func describing the function that contains the
119 // given program counter address, or else nil.
121 // If pc represents multiple functions because of inlining, it returns
122 // the *Func describing the outermost function.
123 func FuncForPC(pc
uintptr) *Func
{
124 name
, _
, _
:= funcfileline(pc
, -1)
128 entry
:= funcentry(pc
)
129 return &Func
{name
: name
, entry
: entry
}
132 // Name returns the name of the function.
133 func (f
*Func
) Name() string {
140 // Entry returns the entry address of the function.
141 func (f
*Func
) Entry() uintptr {
148 // FileLine returns the file name and line number of the
149 // source code corresponding to the program counter pc.
150 // The result will not be accurate if pc is not a program
152 func (f
*Func
) FileLine(pc
uintptr) (file
string, line
int) {
153 _
, file
, line
= funcfileline(pc
, -1)
157 // implemented in go-caller.c
158 func funcfileline(uintptr, int32) (string, string, int)
159 func funcentry(uintptr) uintptr