diff options
author | Simon Marlow <marlowsd@gmail.com> | 2010-04-20 12:21:25 +0000 |
---|---|---|
committer | Simon Marlow <marlowsd@gmail.com> | 2010-04-20 12:21:25 +0000 |
commit | 870b59f53cb97904096bfd6ea0e58ffc055a14ea (patch) | |
tree | 08d13d098df4f1b7e49579aa4acbc9d83802f04c /rts/HeapStackCheck.cmm | |
parent | 5a252eb7bbbe655f63f65e012b8176fd1dd6953f (diff) | |
download | haskell-870b59f53cb97904096bfd6ea0e58ffc055a14ea.tar.gz |
Fix crash in non-threaded RTS on Windows
The tso->block_info field is now overwritten by pushOnRunQueue(), but
stg_block_async_info was assuming that it still held a pointer to the
StgAsyncIOResult. We must therefore save this value somewhere safe
before putting the TSO on the run queue.
Diffstat (limited to 'rts/HeapStackCheck.cmm')
-rw-r--r-- | rts/HeapStackCheck.cmm | 17 |
1 files changed, 8 insertions, 9 deletions
diff --git a/rts/HeapStackCheck.cmm b/rts/HeapStackCheck.cmm index f8195768fb..d17961145a 100644 --- a/rts/HeapStackCheck.cmm +++ b/rts/HeapStackCheck.cmm @@ -662,24 +662,24 @@ stg_block_throwto } #ifdef mingw32_HOST_OS -INFO_TABLE_RET( stg_block_async, RET_SMALL ) +INFO_TABLE_RET( stg_block_async, RET_SMALL, W_ unused ) { W_ ares; W_ len, errC; - ares = StgTSO_block_info(CurrentTSO); + ares = Sp(1); len = StgAsyncIOResult_len(ares); errC = StgAsyncIOResult_errCode(ares); - StgTSO_block_info(CurrentTSO) = NULL; foreign "C" free(ares "ptr"); R1 = len; + Sp_adj(1); Sp(0) = errC; jump %ENTRY_CODE(Sp(1)); } stg_block_async { - Sp_adj(-1); + Sp_adj(-2); Sp(0) = stg_block_async_info; BLOCK_GENERIC; } @@ -687,20 +687,19 @@ stg_block_async /* Used by threadDelay implementation; it would be desirable to get rid of * this free()'ing void return continuation. */ -INFO_TABLE_RET( stg_block_async_void, RET_SMALL ) +INFO_TABLE_RET( stg_block_async_void, RET_SMALL, W_ ares ) { W_ ares; - ares = StgTSO_block_info(CurrentTSO); - StgTSO_block_info(CurrentTSO) = NULL; + ares = Sp(1); foreign "C" free(ares "ptr"); - Sp_adj(1); + Sp_adj(2); jump %ENTRY_CODE(Sp(0)); } stg_block_async_void { - Sp_adj(-1); + Sp_adj(-2); Sp(0) = stg_block_async_void_info; BLOCK_GENERIC; } |