I want to collect all call-sites where a particular function is called. Roughly, I want to sprinkle
mark(@src());
calls around my code, and get something like
pub const mark_locations: []Location = ???
This is the same shaper of the problem as @import("builtin").test_functions.
Are there some ready to use recipes for this in Zig?
I know that this problem can be solved at the linker level. Basically, when you declare a linker symbol, you can instruct the liner “please put this symbol to an array with all similar symbols”, and then get a handle to that array. linkme - Rust implements this for Rust.
That would be a perfect fit for function instrumentation. I wrote a profiler a while back, where I tracked the path through the code with --finstrument-functions, but that was C and Fortran code. Would be nice if it would be possible in zig as well.
I am writing a fuzz test, and I want the test to be able to reflect on the runtime behavior of the program under test. Essentially, coverage, but:
I only care about specific logical conditions in my code, not line coverage,
I want this to work with vanilla zig build test, without any extra runtime libraries, processes, or compilation flags
I want to feed the information into the running program as it runs (so, it needs to be an array of counters, rather than an .html file, and I need to get it from inside the process).
The result should be deterministic across targets and optimization modes
So actually you can put SrcRegistry in the root source file, and have it, at comptime, recursively @embedFile everything that’s imported, by looking for @import statements (which must use a string literal).
It’s a shame @src()doesn’t work outside a function scope, if it did you’d be able to define a single const MyGenericT = MyGeneric(T, @src());once, and then use the two source locations together to uniquely identify a more specific combination.
I guess you could do such an alias as a parameterless type function though?
I have a similar mechanism to what you described in my project which I call a “linker set”, see here, the idea is that you define a linker set and at comptime you can insert objects into it, e.g:
Make the callee noinline and then use @returnAddress. It’s remarkably portable and it gives you a usize corresponding to the call machine code instruction at the call site. You can later resolve these usize values into source locations (line, column, file) based on debug info.