Drawbacks of using /LARGEADDRESSAWARE for 32-bit Windows executables?

blindly applying the LargeAddressAware flag to your 32bit executable deploys a ticking time bomb!

by setting this flag you are testifying to the OS:

yes, my application (and all DLLs being loaded during runtime) can cope with memory addresses up to 4 GB.
so don’t restrict the VAS for the process to 2 GB but unlock the full range (of 4 GB)”.

but can you really guarantee?
do you take responsibility for all the system DLLs, microsoft redistributables and 3rd-party modules your process may use?

usually, memory allocation returns virtual addresses in low-to-high order. so, unless your process consumes a lot of memory (or it has a very fragmented virtual address space), it will never use addresses beyond the 2 GB boundary. this is hiding bugs related to high addresses.

if such bugs exist they are hard to identify. they will sporadically show up “sooner or later”. it’s just a matter of time.

luckily there is an extremely handy system-wide switch built into the windows OS:
for testing purposes use the MEM_TOP_DOWN registry setting.
this forces all memory allocations to go from the top down, instead of the normal bottom up.

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management]
"AllocationPreference"=dword:00100000

(this is hex 0x100000. requires windows reboot, of course)

with this switch enabled you will identify issues “sooner” rather than “later”.
ideally you’ll see them “right from the beginning”.

side note: for first analysis i strongly recommend the tool VMmap (SysInternals).

conclusions:

when applying the LAA flag to your 32bit executable it is mandatory to fully test it on a x64 OS with the TopDown AllocationPreference switch set.

for issues in your own code you may be able to fix them.
just to name one very obvious example: use unsigned integers instead of signed integers for memory pointers.

when encountering issues with 3rd-party modules you need to ask the author to fix his bugs. unless this is done you better remove the LargeAddressAware flag from your executable.


a note on testing:

the MemTopDown registry switch is not achieving the desired results for unit tests that are executed by a “test runner” that itself is not LAA enabled.
see: Unit Testing for x86 LargeAddressAware compatibility


PS:
also very “related” and quite interesting is the migration from 32bit code to 64bit.
for examples see:

Leave a Comment