We have a library that deals with many aspects of error reporting. I have been tasked to port this library to Linux. When running though my little test suite, one of the
Here's a potential solution. It's probably rather complex to implement, and certainly at least part of it needs re-implemented per CPU archicture and OS and/or C-library combination:
In the signal handler, the stack contains a saved copy of all the registers of the interrupted code. You can manipulate this to modify program state once the signal handler exits. You'd want to do something like this in the handler:
1) Move the bottom part of the stack down (current stack frame, the CPU state the kernel saved, whatever is required for the handler to return back into the kernel) in memory.
2) In the spare space in the middle of the stack, invent a new stack frame as if some "exception invocation" function had been executing when the signal was raised. This frame should be laid out exactly in the same manner as if the interrupted code had called this function in a normal way.
3) Modify the saved CPU state's PC to point at this "exception invocation" function.
4) Exit the signal handler.
The signal handler will return to the kernel. The kernel will return back to this new stack frame (the "exception invocation" function) instead of the original code. This "exception invocation" function should simply raise whatever exception that you want raised.
There are probably a few details here; e.g.:
1) The "exception invocation" function probably needs to save a bunch of registers onto the stack that it normally wouldn't; i.e. all the callee-saved registers that the interrupted code may have been using. You might need to write (part of?) the "exception invocation" function in assembly to assist here. Perhaps step 2 above could save the registers as part of setting up the stack frame.
2) The signal handler is messing about with the stack. This will confuse compiler-generated code a lot. You probably have to write the exception handler (or just perhaps some function it calls, which would require moving more stack frames) in assembly to make this work.
3) You might need to manually generate some C++ exception handler unwind information so that the C++ exception handling code knows how to unwind the stack out of this "exception invocation" function. If you can write the function in C++, probably not. If you can't, then almost certainly.
4) Probably all kinds of nasty details I've overlooked:-)