Skip to content

Commit

Permalink
stacktrace: handle inlining in AppendCallerFrames
Browse files Browse the repository at this point in the history
Update AppendCallerFrames to take a maximum number
of frames to append. Multiple frames may share a
PC, so it is not enough to just supply the callers
if we want to limit the output. If the supplied
count is negative, return all frames as before.
  • Loading branch information
axw committed Jun 27, 2018
1 parent b69284b commit df9ddf0
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 7 deletions.
2 changes: 1 addition & 1 deletion error.go
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ func initStacktrace(e *Error, err error) {
for i, frame := range stackTrace {
pc[i] = uintptr(frame)
}
e.stacktrace = stacktrace.AppendCallerFrames(e.stacktrace[:0], pc)
e.stacktrace = stacktrace.AppendCallerFrames(e.stacktrace[:0], pc, -1)
}
}

Expand Down
14 changes: 8 additions & 6 deletions stacktrace/stacktrace.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func AppendStacktrace(frames []Frame, skip, n int) []Frame {
pc = pc[:runtime.Callers(skip+1, pc)]
} else {
// n is negative, get all frames.
n = 0
n := 0
pc = make([]uintptr, 10)
for {
n += runtime.Callers(skip+n+1, pc[n:])
Expand All @@ -38,19 +38,21 @@ func AppendStacktrace(frames []Frame, skip, n int) []Frame {
pc = append(pc, 0)
}
}
return AppendCallerFrames(frames, pc)
return AppendCallerFrames(frames, pc, n)
}

// AppendCallerFrames appends to frames for the PCs in callers,
// and returns the extended slice.
// AppendCallerFrames appends to n frames for the PCs in callers,
// and returns the extended slice. If n is negative, all available
// frames will be added. Multiple frames may exist for the same
// caller/PC in the case of function call inlining.
//
// See RuntimeFrame for information on what details are included.
func AppendCallerFrames(frames []Frame, callers []uintptr) []Frame {
func AppendCallerFrames(frames []Frame, callers []uintptr, n int) []Frame {
if len(callers) == 0 {
return frames
}
runtimeFrames := runtime.CallersFrames(callers)
for {
for i := 0; n < 0 || i < n; i++ {
runtimeFrame, more := runtimeFrames.Next()
frames = append(frames, RuntimeFrame(runtimeFrame))
if !more {
Expand Down

0 comments on commit df9ddf0

Please sign in to comment.