2023-09-02 17:24:18 +08:00
|
|
|
package runtimex
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"fmt"
|
2023-09-03 13:04:29 +08:00
|
|
|
"path/filepath"
|
2023-09-02 17:24:18 +08:00
|
|
|
"runtime"
|
|
|
|
|
"strings"
|
|
|
|
|
)
|
|
|
|
|
|
2024-10-16 17:24:50 +08:00
|
|
|
// StackStr 获取指定堆栈描述信息
|
2023-09-02 17:24:18 +08:00
|
|
|
//
|
|
|
|
|
// @param skip: 跳过堆栈个数
|
|
|
|
|
// @param nFrames: 需要描述的堆栈个数
|
2024-10-16 17:24:50 +08:00
|
|
|
func StackStr(skip, nFrames int) string {
|
2023-09-02 17:24:18 +08:00
|
|
|
pcs := make([]uintptr, nFrames+1)
|
|
|
|
|
n := runtime.Callers(skip+1, pcs)
|
|
|
|
|
if n == 0 {
|
|
|
|
|
return "(no stack)"
|
|
|
|
|
}
|
|
|
|
|
frames := runtime.CallersFrames(pcs[:n])
|
|
|
|
|
var b strings.Builder
|
|
|
|
|
i := 0
|
|
|
|
|
for {
|
|
|
|
|
frame, more := frames.Next()
|
2023-09-03 13:04:29 +08:00
|
|
|
fmt.Fprintf(&b, "called from %s (%s:%d)\n\t", frame.Function, filepath.Base(frame.File), frame.Line)
|
2023-09-02 17:24:18 +08:00
|
|
|
if !more {
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
i++
|
|
|
|
|
if i >= nFrames {
|
|
|
|
|
fmt.Fprintf(&b, "(rest of stack elided...)\n")
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return b.String()
|
|
|
|
|
}
|