Skip to content

Commit

Permalink
fix file-based filtering symbolization
Browse files Browse the repository at this point in the history
If file-filtered logging is enabled, V looks up its caller's source
file path using runtime.Callers and runtime.FuncForPC. However,
runtime.Callers returns return PCs, which aren't necessarily in the
same source file as the call site. For example, if F calls V, and F's
call to V is immediately followed by an inlined called to another
function, say G, then symbolizing V's return PC will actually return
G's file and line number, not F's.

Fix this by subtracting 1 from the PC returned by runtime.Callers to
back up from the return PC to the call PC.

An arguably better fix would be to use runtime.CallersFrames, which
abstracts away such details. Unfortunately, CallersFrames allocates
(at least as of Go 1.15), so we avoid it here.
  • Loading branch information
aclements authored and dims committed Sep 2, 2021
1 parent e1f317b commit d648c2e
Showing 1 changed file with 7 additions and 2 deletions.
9 changes: 7 additions & 2 deletions klog.go
Original file line number Diff line number Diff line change
Expand Up @@ -1328,9 +1328,14 @@ func V(level Level) Verbose {
if runtime.Callers(2, logging.pcs[:]) == 0 {
return newVerbose(level, false)
}
v, ok := logging.vmap[logging.pcs[0]]
// runtime.Callers returns "return PCs", but we want
// to look up the symbolic information for the call,
// so subtract 1 from the PC. runtime.CallersFrames
// would be cleaner, but allocates.
pc := logging.pcs[0] - 1
v, ok := logging.vmap[pc]
if !ok {
v = logging.setV(logging.pcs[0])
v = logging.setV(pc)
}
return newVerbose(level, v >= level)
}
Expand Down

0 comments on commit d648c2e

Please sign in to comment.