Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Drawbacks of using /LARGEADDRESSAWARE for 32 bit Windows executables?

We need to link one of our executables with this flag as it uses lots of memory.
But why give one EXE file special treatment. Why not standardize on /LARGEADDRESSAWARE?

So the question is: Is there anything wrong with using /LARGEADDRESSAWARE even if you don't need it. Why not use it as standard for all EXE files?

like image 348
Arve Avatar asked Feb 18 '10 13:02

Arve


People also ask

How to increase the memory limit for 32-bit applications in windows 64-bit OS?

One of the simplest ways to increase the amount of memory a process can use on 32-bit Windows is to enable the /3GB flag in the Windows' boot. ini file. This has the effect of adjusting the kernel/user address space split in favour of the application by 1GB, i.e. instead of a 2GB/2GB split you have a 3GB/1GB split.

How to make EXE LARGE address aware?

To make your application large address aware you should open the properties for your project and navigate to the “Linker -> System” page. On this page you should set the “Enable large addresses” property to “Yes (/LARGEADDRESSAWARE)”.

What is Largeaddressaware?

Large Address Aware (LAA) is a technique available in 64-bit Windows operating systems to allow 32-bit programs use all 4Gb (typically 2Gb user + 2Gb system space) of its potential memory space, rather than be limited by the default (typically 2Gb, but sometimes 3Gb if using special techniques).


2 Answers

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:

  • As a programmer, what do I need to worry about when moving to 64-bit windows?
  • https://www.sec.cs.tu-bs.de/pubs/2016-ccs.pdf (twice the bits, twice the trouble)
like image 152
Opmet Avatar answered Sep 22 '22 13:09

Opmet


Because lots of legacy code is written with the expectation that "negative" pointers are invalid. Anything in the top two Gb of a 32bit process has the msb set.

As such, its far easier for Microsoft to play it safe, and require applications that (a) need the full 4Gb and (b) have been developed and tested in a large memory scenario, to simply set the flag.

It's not - as you have noticed - that hard.

Raymond Chen - in his blog The Old New Thing - covers the issues with turning it on for all (32bit) applications.

like image 42
Chris Becke Avatar answered Sep 22 '22 13:09

Chris Becke