I’m using the LLVM exception handling intrinsics, along with a custom personality function, to do exception handling and it is working well. Now, I would like to add the ability to produce a human-readable stack backtrace for exceptions which are not caught (or rather, which are caught by some top-level function which prints the exception’s stack trace).
I’m assuming that the way to make this work is to modify the exception personality function to capture information about the stack. Unfortunately, none of my experiments in this area have yielded anything useful.
For example, I have experimented with calling _Unwind_Backtrace from the personality function, but this only yields an _Unwind_Context pointer which is of limited use. It’s hard to tell because most of the structures are opaque, but it appears as though the information I’m getting from _Unwind_Backtrace has little or no relation to the state of the stack at the time the exception was actually thrown. It may be that what I am getting is the stack at the point of the catch statement, which isn’t terribly useful for this purpose. But as I say, it’s hard to tell.
I thought about using libunwind functions directly (unw_step and such), but it doesn’t appear that libunwind is available on OS X.
I’ve also tried using the ‘backtrace’ function from execinfo.h, but again the information I get when I call it from within the personality function doesn’t appear to have much relation to the call stack at the time the exception is thrown.
What I would like to solve is the following problems:
After a successful phase 1 (search phase) of the unwind, I’d like to get information about all stack frames that are in-between the initial throwing frame, and the frame that actually handled the exception. In other words, the search phase would proceed as normal, and then during phase 2 (handler/cleanup phase) it would incrementally build a list of frame infos for each frame.
Given a frame, a way to determine the DWARF debug information for that function. Given an _Unwind_Context, it is easy to get the program counter for that frame, so I assume that this is just a matter of converting the program counter to a function name.
Similarly, I’d like some means to determine the current line number that corresponds to the program counter value for a given frame.
Bear in mind that I am not using any of the C++ library functions, my exception handling code is using unwind.h directly and does not link with any of the C++ libraries.