Dave Korn <dave.korn.cyg...@googlemail.com> writes: > Ian Lance Taylor wrote: > >> First, an exception can occur while executing an instruction which >> accesses memory or does a division (admittedly only within a __try >> block). The raise exception call, on the other hand, can only occur >> during a function call. gcc's -fasynchronous-unwind-tables option is >> intended to support unwinding the stack at any precise instruction >> boundary, which might be adequate for this purpose if the OS can handle >> the adjustment from an exception in the middle of an instruction to an >> exception after the previous instruction is complete. Unfortunately, >> -fasynchronous-unwind-tables doesn't work; unwinding the stack during a >> function epilogue is not handled correctly. > > In most cases it would be a safe assumption that no exceptions are thrown > during a prologue, but not if your stack got corrupted I suppose. Would there > be any fundamental difficulty in fixing -fa-u-t?
No fundamental difficulty that I know of. Lots of tedious work for every backend setting RTX_FRAME_RELATED_P and adding REG_FRAME_RELATED_EXPR notes to the manually constructed epilogue insns. And, in fact, I was wrong in saying that exception could only occur during specific types of instructions. As far as I can see, with SEH exceptions can occur at any time: consider signal handlers. >> Second, it sounds like SEH permits execution to resume at the point of >> the exception, by having the exception handler function return >> ExceptionContinueExecution. I don't know how this could be implemented >> safely; it implies that the exception handler has some knowledge of how >> the program is compiled. I think the only possibility here is to just >> say that any use of ExceptionContinueException is undefined behaviour. >> This is unlikely to be satisfactory when porting existing programs, but >> perhaps that is not a significant consideration here. Also, the main >> reason for supporting SEH in gcc is so that it works with C++ >> exceptions, and they will never return ExceptionContinueException. > > I don't think I see your point. The exception handler is not invoked > directly, but is called by the unwinder in the runtime library. The exception > handler is part of the program. It doesn't know how the program is compiled, > it just knows that it's the exception handler for a block of code where > there's (e.g.) a divide operation. It resets the variable in the outer scope > from zero to one and returns E-C-E. The runtime knows how to reset the > current thread's context and continue. (The entry to the EH unwinder is very > much like a longjmp, it preserves all the relevant context). Whether or not > it's a sensible or safe thing to do is a decision in the hands of the > application programmer. How does the exception handler know how to "reset the variable in the outer scope?" With gcc, that variable may simultaneously live in multiple different registers and could even live in two different memory locations (e.g., a global variable which was loaded into a register and then spilled to the stack during reload). Ian