5

Colleagues convert a 32 bit C++ application to 64 Bit. For testing purposes, the idea is now to instruct the heap manager to return addresses in the 64 bit range only.

Searching the Internet for solutions does not seem to give very reliable results:

  • MSDN forums suggest to use VirtualAlloc()before the CRT initializes. However, I can't see why that should not return a pointer to a high address already, leaving the bottom 4 GB empty.

  • Raymond Chen says, Windows 7 has a switch called Allocation­Preference which can be set to MEM_TOP_DOWN. However, that applies to the whole system and thus requires a reboot, which is inconvenient. (also described on MSDN).

I dug around in application verifier and found some interesting options in the properties of the Heaps entry:

Application verifier

As you can see I have modified SizeStart and SizeEnd as well as AddrStart and AddrEnd.

Unfortunately,

  1. these text boxes do not accept 64 bit addresses
  2. these settings do not seem to have an effect

While the addresses are above the entered values, the size of the heaps has not changed:

Termination on corruption : ENABLED
          Heap     Flags   Reserv  Commit  Virt   Free  List   UCR  Virt  Lock  Fast 
                            (k)     (k)    (k)     (k) length      blocks cont. heap 
-------------------------------------------------------------------------------------
000001e0aa590000 00000002    2040   1528   2040      3     1     2    0      0      
000001e0aa440000 00001002    1080    248   1080      2     2     2    0      0      
000001e0aa410000 00008000      64      4     64      2     1     1    0      0      
000001e0aa520000 00001002    1080    104   1080      1     2     2    0      0      
000001e0af2f0000 00001002      60     60     60      6     1     1    0      0      
-------------------------------------------------------------------------------------

Do these application verifier settings still work? How to apply them successfully?

Lieven Keersmaekers
  • 57,207
  • 13
  • 112
  • 146
Thomas Weller
  • 55,411
  • 20
  • 125
  • 222
  • Interesting question, I suspect that individual heap allocations are limited to some nominal limit (could be 4GB but I can't find any reference on this) but that the heap pool limit is dependent on OS version. You could do what Raymond suggests and reserve the first 4GB on init to force further allocations into the above 4GB address space if setting that flag and rebooting is too much of a pain. Also doesn't surprise me that some of these options and flags may not work, the latest version of app verifier doesn't work for me, had to use an older version – EdChum Nov 20 '19 at 16:27
  • Running on Win8.1 or higher is the easiest way, those versions always allocate above 4GB. Looks like you've got Win10 so you're good to go. – Hans Passant Nov 20 '19 at 18:07
  • 1
    @MarekR: well, there used to be a time when people misused parts of pointers to transfer an additional bit in the highest position of a pointer. That's why we have all that stuff like LargeAddressAware. – Thomas Weller Nov 20 '19 at 20:43

1 Answers1

0

As @HansPassant mentioned in the comments, Windows 8 allocates above the 4 GB limit. This is because 64 Bit applications are compiled with /HIGHENTROPYVA flag by default as mentioned in Raymond Chen's "The old new thing" blog post.

For Windows 7, the idea is to use VirtualQuery(), check for MEM_FREE and then allocate all these regions with VirtualAlloc() where you can pass the address to be allocated.

Thomas Weller
  • 55,411
  • 20
  • 125
  • 222