Unwind information incorrect between Sp adjustment and end of block
As pointed out in D1532, the DWARF unwinding information that we produce is currently a bit oversimplified. Namely, we produce exactly one unwind table per Cmm block. This, however, produces subtly incorrect debug information,
aProcedure() {
casl:
-- we just entered the procedure, so the unwinding is trivial.
unwind Sp = Sp
-- we push some values onto the stack...
I64[Sp - 16] = ...
I64[Sp - 8] = ...
-- and before leaving the block we update Sp.
Sp = Sp - 16;
-- technically our unwind information is now a lie
call aFunction() returns to casd;
casd:
-- we inherit the unwind information from the state of the stack when we
-- left the preceding block (casl)
unwind Sp = Sp + 16
R2 = I64[Sp + 8];
-- pop off that which we pushed
Sp = Sp + 16;
call GHC.List.$wunsafeTake_info(R3, R2) args: 8, res: 0, upd: 8;
}
Here there is a narrow window where our unwind information is technically wrong:
between updating Sp
in casl
and calling into aFunction
.
Note that after we arrive in aFunction
we are safe, since our return address
is casd
, which has the correct unwinding information.