summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Gamari <ben@smart-cactus.org>2019-06-24 15:37:12 -0400
committerAndreas Klebinger <klebinger.andreas@gmx.at>2021-08-03 12:08:57 +0000
commitf29d897a344095299580beea94c227286f07c92b (patch)
tree4ec1c7b6e18e1a47c428e65db8487a4afaae3c27
parent34e352173dd1fc3cd86c49380fda5a4eb5dd7aef (diff)
downloadhaskell-wip/clear-bdescr-free.tar.gz
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.h5
-rw-r--r--rts/sm/Storage.c8
-rwxr-xr-x[-rw-r--r--]testsuite/tests/rts/flags/T20006.hs0
3 files changed, 13 insertions, 0 deletions
diff --git a/includes/rts/storage/Block.h b/includes/rts/storage/Block.h
index 626cddb2a2..a1db4edadd 100644
--- a/includes/rts/storage/Block.h
+++ b/includes/rts/storage/Block.h
@@ -107,6 +107,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 nonmoving_segment;
};
diff --git a/rts/sm/Storage.c b/rts/sm/Storage.c
index 7d450a8931..b29c734f81 100644
--- a/rts/sm/Storage.c
+++ b/rts/sm/Storage.c
@@ -828,6 +828,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
diff --git a/testsuite/tests/rts/flags/T20006.hs b/testsuite/tests/rts/flags/T20006.hs
index d82a4bd93b..d82a4bd93b 100644..100755
--- a/testsuite/tests/rts/flags/T20006.hs
+++ b/testsuite/tests/rts/flags/T20006.hs