From 891cc466c957e91c7770f0a91ba83b65a268c2c1 Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Fri, 3 Oct 2014 11:37:52 +0200 Subject: erts: Fix bug when delayed deallocated carrier is reused by cpool_fetch The delayed dealloc queue destroyes one word but cpool_fetch() is expected to return healthy carriers. So we restore that overwritten word with a little bit of hackish code. --- erts/emulator/beam/erl_alloc_util.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'erts') diff --git a/erts/emulator/beam/erl_alloc_util.c b/erts/emulator/beam/erl_alloc_util.c index a4e164bf51..55052430e1 100644 --- a/erts/emulator/beam/erl_alloc_util.c +++ b/erts/emulator/beam/erl_alloc_util.c @@ -1775,6 +1775,18 @@ handle_delayed_dealloc(Allctr_t *allctr, * data has been overwritten by the queue. */ Carrier_t *crr = FIRST_BLK_TO_MBC(allctr, blk); + + /* Restore word overwritten by the dd-queue as it will be read + * if this carrier is pulled from dc_list by cpool_fetch() + */ + ERTS_ALC_CPOOL_ASSERT(FBLK_TO_MBC(blk) != crr); + ERTS_ALC_CPOOL_ASSERT(sizeof(ErtsAllctrDDBlock_t) == sizeof(void*)); +#ifdef MBC_ABLK_OFFSET_BITS + blk->u.carrier = crr; +#else + blk->carrier = crr; +#endif + ERTS_ALC_CPOOL_ASSERT(ERTS_ALC_IS_CPOOL_ENABLED(allctr)); ERTS_ALC_CPOOL_ASSERT(allctr == crr->cpool.orig_allctr); ERTS_ALC_CPOOL_ASSERT(((erts_aint_t) allctr) -- cgit v1.2.3