mirror of https://github.com/docker/cli.git
66 lines
1.2 KiB
Go
66 lines
1.2 KiB
Go
package errors
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"runtime"
|
|
)
|
|
|
|
// Call holds a call frame
|
|
type Call runtime.Frame
|
|
|
|
// Location is the parsed file, line, and other info we can determine from
|
|
// a specific gostack.Call.
|
|
type Location struct {
|
|
File string
|
|
Line int
|
|
Func string
|
|
}
|
|
|
|
// Location uses the gostack package to construct file, line, and other
|
|
// info about this call.
|
|
func (c Call) Location() *Location {
|
|
return &Location{
|
|
File: c.File,
|
|
Line: c.Line,
|
|
Func: c.Function,
|
|
}
|
|
}
|
|
|
|
// MarshalJSON returns the JSON representation.
|
|
func (c Call) MarshalJSON() ([]byte, error) {
|
|
m := make(map[string]interface{})
|
|
loc := c.Location()
|
|
m["file"] = loc.File
|
|
m["line"] = loc.Line
|
|
m["func"] = loc.Func
|
|
return json.Marshal(m)
|
|
}
|
|
|
|
func (c Call) String() string {
|
|
return fmt.Sprintf("%v:%v", c.File, c.Line)
|
|
}
|
|
|
|
// CallStack is a convenience alias for a call stack.
|
|
type CallStack []Call
|
|
|
|
// CurrentCallStack returns the call stack, skipping the specified
|
|
// depth of calls.
|
|
func CurrentCallStack(skip int) CallStack {
|
|
var pcs [128]uintptr
|
|
n := runtime.Callers(skip+2, pcs[:])
|
|
|
|
callersFrames := runtime.CallersFrames(pcs[:n])
|
|
cs := make([]Call, 0, n)
|
|
|
|
for {
|
|
frame, more := callersFrames.Next()
|
|
cs = append(cs, Call(frame))
|
|
if !more {
|
|
break
|
|
}
|
|
}
|
|
|
|
return cs
|
|
}
|