slog's use of runtime.Callers() with a skip

564 views
Skip to first unread message

sh...@tigera.io

unread,
Aug 4, 2023, 9:51:34 AM8/4/23
to golang-nuts
I was looking at replacing logrus with the new slog library in our project.  I noticed that it uses runtime.Callers() with a fixed skip to collect the PC of the calling code, presumably to make it possible for the handler to emit line number and filename.

Question is: is that sound in the face of inlining functions?  I think if the Info method gets inlined then the skip might be too large, for example.

I remember having to change similar code in our project to use runtime.CallersFrames in order to deal with inlining. Quite possible there's a way to deal with an inlined PC that I wasn't aware of, but it seemed wrong to me.

-Shaun

jake...@gmail.com

unread,
Aug 11, 2023, 8:58:53 AM8/11/23
to golang-nuts
As far as I can tell, skip works even in the face of inlined functions, at least when used with runtime.CallersFrames(). It would be surprising  to me if it did not. Do you have any evidence to the contrary?

Jonathan Amsterdam

unread,
Aug 11, 2023, 10:57:20 PM8/11/23
to golang-nuts
The Go runtime does the right thing.

Shaun Crampton

unread,
Aug 14, 2023, 7:07:31 AM8/14/23
to Jonathan Amsterdam, golang-nuts
Do you have any evidence to the contrary?

Only that when Go 1.12 dropped, our similar function stopped working and that reducing the skip seemed to do the trick.

The symptom was that our function would see an assembly file as the caller, which I interpreted to mean that we'd skipped too far.  It only happened in goroutines with short stacks and I put it down to inlining.

Quite possible that the "fix" I made was mistaken, or that runtime.Callers has been updated/fixed since then.


Looking back, I see three changes in that "fix":
  • Change to skip from 6 to 1 (and increase pcs buffer size accordingly).
  • Reslice pcs to the valid portion, looks like we missed that before; possible this was the "real" fix?
  • Change the list of file names that we skip.
We were already using CallersFrames before the fix.

The Go runtime does the right thing.

It does seem to in my local tests with up-to-date Go; i tried some toy examples and checked that functions really were being inlined.
Reply all
Reply to author
Forward
0 new messages