This RTS has the restriction No_Exception_Propagation
.
This means that any unhandled exception in a subprogram will immediately result in a call to Last_Chance_Handler
, which won't return.
Also, you can't use the raise
statement to do partial handling, as in
declare Err : exception; begin begin raise Err with "test"; exception when Err => -- partial cleanup raise; -- this is not permitted end; exception when Err => null; -- this is OK end;
The RTS's last chance exception handler is written as
__attribute__((weak)) void __gnat_last_chance_handler(const char *message, int line) { taskDISABLE_INTERRUPTS(); vTaskSuspendAll(); // Loop indefinitely: use the debugger to examine the backtrace. while (1) {} }
and the weak
attribute means that you can write your own version to do something more immediately useful, provided it matches the spec
procedure Last_Chance_Handler (Message : System.Address; Line : Integer) with Export, Convention => C, External_Name => "__gnat_last_chance_handler";
(but it's much easier to read the exception message in the debugger if you use the C version)
Note that at the moment the Line
parameter is always 0
(this may be affected by the binder argument -E
).
I've made several attempts to support exception handling; unfortunately, it's spread throughout the RTS and requires introducing and modifying many packages. I take some heart from the late Robert Dewar's remarks starting at 16:20 here - "exceptions are a huge pain in the neck to implement".