Skip to content

integer overflow in rts/RtsUtils:heapOverflow()

When failing with a heap exhaustion, the RTS truncates the reported current maximum heap size modulo 2^32, e.g.

$ ghc +RTS -M4G -RTS -e 'sum [1..]'
Heap exhausted;
Current maximum heap size is 0 bytes (0 MB);
use `+RTS -M<size>' to increase it.

This is most probably due to OutOfHeapHook() already being called with the truncated value from heapOverflow():

void
heapOverflow(void)
{
    if (!heap_overflow)
    {
        /* don't fflush(stdout); WORKAROUND bug in Linux glibc */
        OutOfHeapHook(0/*unknown request size*/,
                      RtsFlags.GcFlags.maxHeapSize * BLOCK_SIZE);

        heap_overflow = rtsTrue;
    }
}

which multiplies RtsFlags.GcFlags.maxHeapSize and BLOCK_SIZE whose type are 32-bit unsigned ints, causing the result to be wrapped again into an unsigned int, whereas the result should be upcasted to a long unsigned int (which at least on 64bit archs would be equivalent to a C99 uint64_t)

Trac metadata
Trac field Value
Version 7.2.2
Type Bug
TypeOfFailure OtherFailure
Priority normal
Resolution Unresolved
Component Runtime System
Test case
Differential revisions
BlockedBy
Related
Blocking
CC
Operating system
Architecture
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information