Proposal Details

This proposal is for a function with a signature like func CallerString(skip int) string.

It returns basic info about the caller in some fixed format.

Since it only returns info about a single frame and only reports it as simple data, when skip is a reasonable constant, it could be replaced at compile time as an optimization. Otherwise, it can be implemented in terms of Callers.

Either way, it would simplify common logging/monitoring/error annotating uses that just need a tiny bit of context about a single caller for reporting to a developer.

Comment From: gabyhelp

Related Documentation

(Emoji vote if this was helpful or unhelpful; more detailed feedback welcome in this discussion.)

Comment From: ianlancetaylor

What would the string be?

I'm not sure what you mean when you suggest replacing it at compile time. It seems to me that is only possible when the caller is known. And that can only happen if the function that calls CallerString is only called from one other location in the program. If it's called from more than one location, how can the compiler know what the value of CallerString should be?

Comment From: jimmyfrasche

I doesn't matter precisely what the string is as long as it 1. contains enough information to identify the caller 2. is in a specified format that is human and machine readable

It could just be "path/file:lineNumber". I'm not concerned about the particulars as long as it is meets the listed criteria.

Say you had a function using it like

func F() T {
  return G(runtime.CallerString(1))
} 

I'm imagining some hypothetical set of optimizations where F is inlined and the constant is decremented in kind and thus can be replaced with the information from the original call site for F so when you call F() you end up with a sequence of transformations: F() to G(runtime.CallerString(0)) to G("my/file.go:10") (or whatever format).

Comment From: seankhliao

Without skip it'd be #12876 #27329 #37620

Comment From: jimmyfrasche

It would serve a similar purpose. This is about providing a nicer interface.

The last place I used something like this was a parser for strings that would be provided in source (like how regexp.Compile often takes a constant). Since there could be many of these in the same project, it took used runtime to grab the file/line info so it could report errors not just as an offset into a string but also the source location of that string. I just wanted a string but ended up having to read and reread a bunch of docs. I couldn't tell if it was sufficient to use runtime.Caller(1) or if I needed to do like the example for Frames so that it worked even if things got inlined. I ended up using a modified version of the Frames example just in case but maybe that's overkill. I just wanted to make sure I got some debugging info that seemed like it should be easier to get.

Comment From: seankhliao

52751 sounds related, though that's more specialized to tests

Comment From: adonovan

The runtime package provides all the necessary primitives, and it's not obvious to me from its name what kind of string CallerString would actually return; and I can easily imagine wanting to tweak it a little. This merely convenient feature might be better provided by the internal library within your project, tailored to your specific needs.

Comment From: jimmyfrasche

The necessary primitives are not especially friendly and their generality makes the simple case overly complicated.

Getting basic info about a single frame is the common case by volume and it would be nice to have a clear, simple, robust way to get that.

Comment From: ianlancetaylor

@jimmyfrasche You say above that the string has to be machine readable, which means that it must be precisely defined. This proposal isn't going to go anywhere unless you provide a precise definition. Thanks.