From af9e96991659185821632ff96383480c9dc9cbda Mon Sep 17 00:00:00 2001 From: Simon Marlow Date: Tue, 24 May 2011 16:56:23 +0100 Subject: [PATCH] fix an integer overflow (#5086), and pre-emptively avoid more of these in the future. --- includes/rts/storage/GC.h | 26 +++++++++++++++++--------- rts/Stats.c | 2 +- rts/sm/GC.c | 2 +- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/includes/rts/storage/GC.h b/includes/rts/storage/GC.h index bbed216..3c6e6f6 100644 --- a/includes/rts/storage/GC.h +++ b/includes/rts/storage/GC.h @@ -53,24 +53,32 @@ * * ------------------------------------------------------------------------- */ +// A count of blocks needs to store anything up to the size of memory +// divided by the block size. The safest thing is therefore to use a +// type that can store the full range of memory addresses, +// ie. StgWord. Note that we have had some tricky int overflows in a +// couple of cases caused by using ints rather than longs (e.g. #5086) + +typedef StgWord memcount; + typedef struct nursery_ { bdescr * blocks; - unsigned int n_blocks; + memcount n_blocks; } nursery; typedef struct generation_ { unsigned int no; // generation number bdescr * blocks; // blocks in this gen - unsigned int n_blocks; // number of blocks - unsigned int n_words; // number of used words + memcount n_blocks; // number of blocks + memcount n_words; // number of used words bdescr * large_objects; // large objects (doubly linked) - unsigned int n_large_blocks; // no. of blocks used by large objs - unsigned long n_new_large_words; // words of new large objects + memcount n_large_blocks; // no. of blocks used by large objs + memcount n_new_large_words; // words of new large objects // (for allocation stats) - unsigned int max_blocks; // max blocks + memcount max_blocks; // max blocks StgTSO * threads; // threads in this gen // linked via global_link @@ -98,11 +106,11 @@ typedef struct generation_ { // are copied into the following two fields. After GC, these blocks // are freed. bdescr * old_blocks; // bdescr of first from-space block - unsigned int n_old_blocks; // number of blocks in from-space - unsigned int live_estimate; // for sweeping: estimate of live data + memcount n_old_blocks; // number of blocks in from-space + memcount live_estimate; // for sweeping: estimate of live data bdescr * scavenged_large_objects; // live large objs after GC (d-link) - unsigned int n_scavenged_large_blocks; // size (not count) of above + memcount n_scavenged_large_blocks; // size (not count) of above bdescr * bitmap; // bitmap for compacting collection diff --git a/rts/Stats.c b/rts/Stats.c index 3036ed7..8366bf4 100644 --- a/rts/Stats.c +++ b/rts/Stats.c @@ -817,7 +817,7 @@ statDescribeGens(void) gen_blocks += gcThreadLiveBlocks(i,g); } - debugBelch("%5d %7d %9d", g, gen->max_blocks, mut); + debugBelch("%5d %7ld %9d", g, (lnat)gen->max_blocks, mut); gen_slop = gen_blocks * BLOCK_SIZE_W - gen_live; diff --git a/rts/sm/GC.c b/rts/sm/GC.c index fb73180..51eab4e 100644 --- a/rts/sm/GC.c +++ b/rts/sm/GC.c @@ -1247,7 +1247,7 @@ prepare_collected_gen (generation *gen) // for a compacted generation, we need to allocate the bitmap if (gen->mark) { - nat bitmap_size; // in bytes + lnat bitmap_size; // in bytes bdescr *bitmap_bdescr; StgWord *bitmap; -- 1.7.10.4