diff options
| author | qrort <[email protected]> | 2022-11-30 23:47:12 +0300 |
|---|---|---|
| committer | qrort <[email protected]> | 2022-11-30 23:47:12 +0300 |
| commit | 22f8ae0e3f5d68b92aecccdf96c1d841a0334311 (patch) | |
| tree | bffa27765faf54126ad44bcafa89fadecb7a73d7 /library/go/x/xruntime/stacktrace.go | |
| parent | 332b99e2173f0425444abb759eebcb2fafaa9209 (diff) | |
validate canons without yatest_common
Diffstat (limited to 'library/go/x/xruntime/stacktrace.go')
| -rw-r--r-- | library/go/x/xruntime/stacktrace.go | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/library/go/x/xruntime/stacktrace.go b/library/go/x/xruntime/stacktrace.go new file mode 100644 index 00000000000..5c5e661188f --- /dev/null +++ b/library/go/x/xruntime/stacktrace.go @@ -0,0 +1,69 @@ +package xruntime + +import ( + "runtime" +) + +type StackTrace struct { + frames []uintptr + full bool +} + +func NewStackTrace16(skip int) *StackTrace { + var pcs [16]uintptr + return newStackTrace(skip+2, pcs[:]) +} + +func NewStackTrace32(skip int) *StackTrace { + var pcs [32]uintptr + return newStackTrace(skip+2, pcs[:]) +} + +func NewStackTrace64(skip int) *StackTrace { + var pcs [64]uintptr + return newStackTrace(skip+2, pcs[:]) +} + +func NewStackTrace128(skip int) *StackTrace { + var pcs [128]uintptr + return newStackTrace(skip+2, pcs[:]) +} + +func newStackTrace(skip int, pcs []uintptr) *StackTrace { + n := runtime.Callers(skip+1, pcs) + return &StackTrace{frames: pcs[:n], full: true} +} + +func NewFrame(skip int) *StackTrace { + var pcs [3]uintptr + n := runtime.Callers(skip+1, pcs[:]) + return &StackTrace{frames: pcs[:n]} +} + +func (st *StackTrace) Frames() []runtime.Frame { + frames := runtime.CallersFrames(st.frames[:]) + if !st.full { + if _, ok := frames.Next(); !ok { + return nil + } + + fr, ok := frames.Next() + if !ok { + return nil + } + + return []runtime.Frame{fr} + } + + var res []runtime.Frame + for { + frame, more := frames.Next() + if !more { + break + } + + res = append(res, frame) + } + + return res +} |
