The ARM Exception Handling ABI requires personality functions in phase1 to initialize barrier_cache before returning _URC_HANDLER_FOUND, and we don't.
Although our own ARM personality function does not use barrier_cache at all, other languages' ARM personality functions, during phase2, are allowed and expected to test barrier_cache.sp to check whether the handler frame was reached, which implies that personality functions is in charge of the frame, and the remaining fields of barrier_cache hold whatever values it put there in phase1. Since we did not set barrier_cache.sp, an earlier exception, already handled by a non-Ada handler and then released, may have its storage reused for a new exception, that phase1 matches to an Ada frame, but if that leaves barrier_cache.sp alone, the phase2 personality function that handled the earlier exception, upon reaching the frame that handled the earlier exception, may believe the information in barrier_cache applies to the current exception. The C++ personality function, for example, would take the information in the barrier_cache and end up activating the handler that handled the earlier exception: try { throw 1; } catch (int i) { std::cout << "caught " << i << " by c++" << std::endl; } raise_ada_exception (); // might loop back to the handler above Regstrapped on x86_64-linux-gnu (no change expected), and tested on ARM-based systems that use the ARM EH ABI. I'm checking this in. for gcc/ada/ChangeLog * raise-gcc.c (personality_body) [__ARM_EABI_UNWINDER__]: Initialize barrier_cache.sp when ending phase1. --- ada/raise-gcc.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git gcc/ada/raise-gcc.c gcc/ada/raise-gcc.c index 1ba8af1..3b6c21fc 100644 --- gcc/ada/raise-gcc.c +++ gcc/ada/raise-gcc.c @@ -1211,6 +1211,16 @@ personality_body (_Unwind_Action uw_phases, } else { +#ifdef __ARM_EABI_UNWINDER__ + /* Though we do not use this field ourselves, initializing + it is required by the ARM EH ABI before a personality + function in phase1 returns _URC_HANDLER_FOUND, so that + any personality function can use it in phase2 to test + whether the handler frame was reached. */ + uw_exception->barrier_cache.sp + = _Unwind_GetGR (uw_context, UNWIND_STACK_REG); +#endif + #ifndef CERT /* Trigger the appropriate notification routines before the second phase starts, when the stack is still intact. First install what -- Alexandre Oliva, freedom fighter he/him https://FSFLA.org/blogs/lxo Free Software Evangelist Stallman was right, but he's left :( GNU Toolchain Engineer FSMatrix: It was he who freed the first of us FSF & FSFLA board member The Savior shall return (true);