-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstack.go
47 lines (37 loc) · 873 Bytes
/
stack.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package mirror
import (
"runtime"
)
const depth = 32
type Stack struct {
ptrs [depth]uintptr
n int
}
// baseSkips is an additional number of skips that must be passed to get the right
// traces. It was derived empirically through testing.
const baseSkips = 1
//go:noinline
func Capture(skip int) Stack {
var stack Stack
stack.n = runtime.Callers(skip+baseSkips+1, stack.ptrs[:])
return stack
}
type Frames struct {
ptrs []uintptr
current []Frame
}
func (stack *Stack) Frames() Frames {
return Frames{
ptrs: stack.ptrs[:stack.n],
}
}
func (frames *Frames) Next() (frame Frame, ok bool) {
for len(frames.current) == 0 {
if len(frames.ptrs) == 0 {
return Frame{}, false
}
frames.current, frames.ptrs = getFrameForPtr(frames.ptrs[0]), frames.ptrs[1:]
}
frame, frames.current = frames.current[0], frames.current[1:]
return frame, true
}