• src/sbbs3/ctrl/sbbsctrl.cpp

    From Rob Swindell (on Windows 11)@VERT to Git commit to main/sbbs/master on Tuesday, July 21, 2026 22:33:23
    https://gitlab.synchro.net/main/sbbs/-/commit/ed0977a8dff6636e4c27074f
    Modified Files:
    src/sbbs3/ctrl/sbbsctrl.cpp
    Log Message:
    sbbsctrl: install a large-address-safe heap manager (GitLab #1185)

    C++Builder 6's classic memory manager is not fully large-address safe.
    It indexes its free-list buckets with signed size arithmetic (an arithmetic-shift divide-by-4) that only goes wrong once the heap arena
    lives above 0x80000000. Since arrivals-24-among (37d2d5a6a0) built sbbsctrl.exe /LARGEADDRESSAWARE, and with Windows serving allocations
    top-down, the Borland arena clusters near ~0xFD000000; a high pointer eventually lands in a block-size header, the manager masks it to a ~2GB
    "size", walks past the end of the arena into freed address space, and
    faults. The crash is an access violation deep in the Borland RTL,
    reached via any innocent alloc/free (a server's log callback appending
    to the GUI, in the observed dumps) - three occurrences on 2026-07-16,
    -18 and -19, the last a WER dump whose stored context localized the
    fault to the memory manager's own block-chain walk.

    Rather than revert LAA and give back the 4GB the original mozjs185 heap-exhaustion crash needs, replace the manager with a thin shim over
    the Windows heap (HeapAlloc/HeapReAlloc/HeapFree on GetProcessHeap()),
    which is large-address safe by construction. It is installed first
    thing in WinMain; the previous Borland manager is saved and chained for
    any block that predates the swap, so every block is freed by the manager
    that allocated it. Each of our blocks carries an 8-byte prefix holding
    a magic word and a self-pointer, making foreign-block detection collision-proof. Post-install allocation churn goes to the OS heap and
    never touches the buggy walker; LAA stays on (build.bat still flips the
    PE bit).

    Tested: sbbsctrl soaked under real load (web server served ~18K clients)
    with system-wide top-down allocation active - the configuration that
    provoked all three prior faults - with no crash.

    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net