Fix bogus use of "long" in AllocSetCheck()
authorDavid Rowley <[email protected]>
Thu, 30 Oct 2025 01:48:10 +0000 (14:48 +1300)
committerDavid Rowley <[email protected]>
Thu, 30 Oct 2025 01:48:10 +0000 (14:48 +1300)
Because long is 32-bit on 64-bit Windows, it isn't a good datatype to
store the difference between 2 pointers.  The under-sized type could
overflow and lead to scary warnings in MEMORY_CONTEXT_CHECKING builds,
such as:

WARNING:  problem in alloc set ExecutorState: bad single-chunk %p in block %p

However, the problem lies only in the code running the check, not from
an actual memory accounting bug.

Fix by using "Size" instead of "long".  This means using an unsigned
type rather than the previous signed type.  If the block's freeptr was
corrupted, we'd still catch that if the unsigned type wrapped.  Unsigned
allows us to avoid further needless complexities around comparing signed
and unsigned types.

Author: David Rowley <[email protected]>
Reviewed-by: Michael Paquier <[email protected]>
Reviewed-by: Tom Lane <[email protected]>
Backpatch-through: 13
Discussion: https://postgr.es/m/CAApHDvo-RmiT4s33J=aC9C_-wPZjOXQ232V-EZFgKftSsNRi4w@mail.gmail.com

src/backend/utils/mmgr/aset.c

index d5ae1bdd3cde409117e87a9a9da231bbb42d206b..bcd09c07533a8b12967a77d0dccf021631a7a898 100644 (file)
@@ -1668,9 +1668,9 @@ AllocSetCheck(MemoryContext context)
         prevblock = block, block = block->next)
    {
        char       *bpoz = ((char *) block) + ALLOC_BLOCKHDRSZ;
-       long        blk_used = block->freeptr - bpoz;
-       long        blk_data = 0;
-       long        nchunks = 0;
+       Size        blk_used = block->freeptr - bpoz;
+       Size        blk_data = 0;
+       Size        nchunks = 0;
        bool        has_external_chunk = false;
 
        if (IsKeeperBlock(set, block))