Description
Useing the 2.1 version of .NET Core, you profile a simple app .NET Core App o (e.g. a spin loop like)
var start = DateTime.Now;
while ((DateTime.Now - start).TotalSeconds < 5)
{}
Using EventPipe (e.g. set COMPlus_EnableEventPipe=1 and run the app) and then open the resulting *.netperf file, you will find that PerfView's 'Goto Source' feature works in the main program, attributing the cost to the correct source line.
However if you open up frames that are inside the framework (e.g. System.TimeZoneInfo.GetLocalTimeZoneFromTzFile) you will find that while PerfView can open the source code (it can correctly find the PDBS for System.Private.Corelib.pdb and the source files on Github), but it will attribute all the cost the the first line in the method.
This is because PerfView lacks the Native->IL mapping needed to map to a particular IL instruction (which in turn can be mapped to a particular line). These normally given to perfView by the ILToNativeMap events in the runtime. (Normally PerfView hides these events when you look at a trace but if you pass PerfView the /keepAllEvents when the trace is converted you can see them).
What you will find is that the mappings exist for all JIT compiled methods (at the time of JIT as well as during rundown), but there are no ILToNativeMap rundown events for DLLs that have been precompiled with Crossgen (which is most of the framework).
We do force the rundown of all methods (DCStopVerbose), that are precompiled (that is how we know the method), but we do currently do this for the ILToNativeMap.
Thus the most straightforward solution is to simply log the ILToNativeMap during this rundown as well.
This will be alot of data, and it may not be needed for simple investigations, but I think it is best to do the simple thing (always include it), and we can talk about having options for turning it off for advanced scenarios that care about file size.