mirror of
https://github.com/ceph/ceph-csi.git
synced 2024-10-19 05:39:51 +00:00
52 lines
1.5 KiB
Go
52 lines
1.5 KiB
Go
|
//go:build go1.18
|
||
|
// +build go1.18
|
||
|
|
||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||
|
// Licensed under the MIT License.
|
||
|
|
||
|
package diag
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"runtime"
|
||
|
"strings"
|
||
|
)
|
||
|
|
||
|
// Caller returns the file and line number of a frame on the caller's stack.
|
||
|
// If the funtion fails an empty string is returned.
|
||
|
// skipFrames - the number of frames to skip when determining the caller.
|
||
|
// Passing a value of 0 will return the immediate caller of this function.
|
||
|
func Caller(skipFrames int) string {
|
||
|
if pc, file, line, ok := runtime.Caller(skipFrames + 1); ok {
|
||
|
// the skipFrames + 1 is to skip ourselves
|
||
|
frame := runtime.FuncForPC(pc)
|
||
|
return fmt.Sprintf("%s()\n\t%s:%d", frame.Name(), file, line)
|
||
|
}
|
||
|
return ""
|
||
|
}
|
||
|
|
||
|
// StackTrace returns a formatted stack trace string.
|
||
|
// If the funtion fails an empty string is returned.
|
||
|
// skipFrames - the number of stack frames to skip before composing the trace string.
|
||
|
// totalFrames - the maximum number of stack frames to include in the trace string.
|
||
|
func StackTrace(skipFrames, totalFrames int) string {
|
||
|
pcCallers := make([]uintptr, totalFrames)
|
||
|
if frames := runtime.Callers(skipFrames, pcCallers); frames == 0 {
|
||
|
return ""
|
||
|
}
|
||
|
frames := runtime.CallersFrames(pcCallers)
|
||
|
sb := strings.Builder{}
|
||
|
for {
|
||
|
frame, more := frames.Next()
|
||
|
sb.WriteString(frame.Function)
|
||
|
sb.WriteString("()\n\t")
|
||
|
sb.WriteString(frame.File)
|
||
|
sb.WriteRune(':')
|
||
|
sb.WriteString(fmt.Sprintf("%d\n", frame.Line))
|
||
|
if !more {
|
||
|
break
|
||
|
}
|
||
|
}
|
||
|
return sb.String()
|
||
|
}
|