First of all, for profiling, I suggest to write addresses only, and then have a tool that runs the data, and resolves the addresses.
This may be a good bit faster than doing them during the run.
Here I'm a bit confused, since the debugger of Lazarus shows me a correct callstack, and I picked up the GetLineInfo hint from looking into Dump_Stack and what it uses back to the Dwarf implementation of the display of callstack information.
The finally (SEH) runs in a function of it's own, hence the name....
But in order to behave like it was the same function as the "try" block is in, the finally uses the "RBP" (base pointer used as stackframe) of the actual function.
Since the RBP is used to find the parent frame, the $fin looks like it has been called by the function that called the "pascal function containing it". So it hides all other callers. In reality it is either called by the OS (some unwind code) or by the "pascal function containing it".
The debug info does not have any link....
--------------
FpDebug does a bit of a trick here.
- The finally must have line numbers in the range of the "pascal function containing it"
- FpDebug finds the first line number of the finally (that may not be on the first address, which could be "begin" being mapped to the "end" line)e
- It then looks up the address of the line right before that (not sure there may be more than one)
- And that address can be used to find the "pascal function containing it"
If that is an other "finally" then recurse.
Mind, you can probably screw that up, if you put to much code on one line....
Not tested with anonymous functions....
------------------
It may be possible to get some info by parsing SEH records... But that is on the TODO list... So no info on it.
Because it has the same "RBP" (base pointer / stackframe)...
In your StartProfiling you could get the frame of the caller (of the function for which you log).
You could store that in a look up list
And in the finally you got look it up.
Of course that may be time consuming