To correctly handle exceptions GCC generates DWARF unwind tables that the runtime uses during unwinding to call the correct destructors but also restore registers and fixup the stack (i.e. the compensation code). Normally unwind tables have entries for each non-noexcept function call in a function as these are the only exception throwing edges. Asynchronous unwind also generates table entries for any instruction that can trap (typically memory accesses, but also things like division, etc). These can be used for example to correctly handle exceptions thrown by signal handlers, which is needed for ADA and Java support.
I had an inline asm statement that could throw exceptions (by indirectly calling exception throwing functions). GCC assumes that asm cannot throw, and the function the statement was in did not have any throw statement nor call any other potentially throwing functions nor any non-optimized out memory access, so the compiler omitted generating unwind tables for the function even with -fasync-unwind-tables.
The result was that throwing from the asm would at best not call destructors, at worse, crash with a corrupted stack.
By adding a non-optimizable dummy memory access right after the asm (and jumping over it from the asm, so it actually doesn't get executed), I forced GCC to generate the unwind info . I also had to make sure that no compensation code was needed for the asm statements themselves, but after that things worked out fine.
I wouldn't really use this in a finished product, it is very fragile and just happened to work on the version of GCC I was using. The right solution would be for GCC to add an attribute to mark asm statements as potentially throwing.
I had long wanted to understand the interplay between -funwind-tables, -fasynchronous-unwind-tables and -fexceptions since the last is language specific but the first two are not. GCC docs are not of much help in understanding what exactly is going on in each case so i guess i need to do some research and experimentation.
I had an inline asm statement that could throw exceptions (by indirectly calling exception throwing functions). GCC assumes that asm cannot throw, and the function the statement was in did not have any throw statement nor call any other potentially throwing functions nor any non-optimized out memory access, so the compiler omitted generating unwind tables for the function even with -fasync-unwind-tables.
The result was that throwing from the asm would at best not call destructors, at worse, crash with a corrupted stack.
By adding a non-optimizable dummy memory access right after the asm (and jumping over it from the asm, so it actually doesn't get executed), I forced GCC to generate the unwind info . I also had to make sure that no compensation code was needed for the asm statements themselves, but after that things worked out fine.
I wouldn't really use this in a finished product, it is very fragile and just happened to work on the version of GCC I was using. The right solution would be for GCC to add an attribute to mark asm statements as potentially throwing.