diff options
author | Ben Gamari <ben@smart-cactus.org> | 2019-06-24 19:37:12 (GMT) |
---|---|---|
committer | Ben Gamari <ben@well-typed.com> | 2019-12-11 18:52:06 (GMT) |
commit | ef0b2280c98618f625914b867bce037c4c814cad (patch) | |
tree | 8c801d85b7139cc66495dc0fcf03d7b5b73e6bff | |
parent | 6e47a76a3d0a7b3d424442914478de579a49363c (diff) | |
download | ghc-wip/clear-bdescr-free.zip ghc-wip/clear-bdescr-free.tar.gz ghc-wip/clear-bdescr-free.tar.bz2 |
rts: Clear bd->free in the DEBUG RTSwip/clear-bdescr-free
In the non-DEBUG RTS we initialize `bd->free` lazily (e.g. when
the mutator starts allocating into the block in stg_gc_noregs).
However, in the past we have had bugs where code looked at
the `free` field of blocks that the mutator never allocated into.
We set the free pointer to NULL to catch this.
This would help to catch #16862.
-rw-r--r-- | includes/rts/storage/Block.h | 5 | ||||
-rw-r--r-- | rts/sm/Storage.c | 8 |
2 files changed, 13 insertions, 0 deletions
diff --git a/includes/rts/storage/Block.h b/includes/rts/storage/Block.h index 4afc368..07ded04 100644 --- a/includes/rts/storage/Block.h +++ b/includes/rts/storage/Block.h @@ -99,6 +99,11 @@ typedef struct bdescr_ { // value (StgPtr)(-1) is used to // indicate that a block is unallocated. // + // Also note that this field is only set lazily + // (e.g. when the mutator starts and stops + // allocating in the nursery stg_gc_noregs) in + // the case of a nursery block. + // // Unused by the non-moving allocator. struct NonmovingSegmentInfo { StgWord8 log_block_size; diff --git a/rts/sm/Storage.c b/rts/sm/Storage.c index 9609ba8..8a33dc8 100644 --- a/rts/sm/Storage.c +++ b/rts/sm/Storage.c @@ -747,6 +747,14 @@ resetNurseries (void) ASSERT(bd->gen == g0); ASSERT(bd->node == capNoToNumaNode(n)); IF_DEBUG(zero_on_gc, memset(bd->start, 0xaa, BLOCK_SIZE)); + + // In the non-DEBUG RTS we initialize bd->free lazily (e.g. when + // the mutator starts allocating into the block in stg_gc_noregs). + // However, in the past we have had bugs (e.g. #16862) where code + // looked at the ->free field of blocks that the mutator never + // allocated into. We set the free pointer to a dummy value + // (0xaaaaa...) to catch this. + IF_DEBUG(sanity, memset(&bd->free, 0xaa, sizeof(bd->free))); } } #endif |