MVar primops are not cheking for stack correctly.
Summary
We use stack space without checking for stack size first.
readMVar will call stg_readMVarzh implemented in PrimOps.cmm. This function itself doesn't use stack.
stg_readMVarzh will call stg_block_readmvar
in HeapStackCheck.cmm:
stg_block_readmvar /* mvar passed in R1 */
{
Sp_adj(-2);
Sp(1) = R1;
Sp(0) = stg_block_readmvar_info;
R3 = R1; // mvar communicated to stg_block_readmvar_finally in R3
BLOCK_BUT_FIRST(stg_block_readmvar_finally);
}
//Compiles to:
stg_block_readmvar() { // []
{ info_tbls: []
stack_info: arg_space: 8 updfr_space: Just 8
}
{offset
c2F:
Sp = Sp - 16;
I64[Sp + 8] = R1;
I64[Sp] = stg_block_readmvar_info;
R3 = R1;
I16[CurrentTSO + 32] = 1 :: W16;
I64[BaseReg + 912] = 4;
R1 = BaseReg;
R2 = stg_block_readmvar_finally;
call stg_returnToSchedButFirst(R1, R2, R3) args: 8, res: 0, upd: 8;
}
Which clearly doesn't perform a stack check when it should.
This was identified by @TerrorJack on the ghc-devs mailing list. I merely confirmed his suspicions and reported it here.
The correct fix is to insert a stack check manually.