Jump to content
A.M. Hoornweg

Large address space awareness. How to test properly?

Recommended Posts

Hello all,

 

I have a 32-bit application written in Delphi XE that I would like to compile with the PE flag "IMAGE_FILE_LARGE_ADDRESS_AWARE", because I'm occasionally nearing the 2 GB RAM limit.  I can't compile this application in 64 bit mode due to dependencies on some 32-bit DLLs.

 

My question:

 

in order to test and debug this in a reasonable time frame, is there any way I can quickly "provoke" any possible lurking bugs (such as pointer math that may still use signed integers somewhere)? For example, is there any way of telling the fastMM4 memory manager to start allocating heap addresses top-down instead of bottoms-up, so that all objects are allocated "above" 2GB ?

 

 

 

Share this post


Link to post
22 minutes ago, Jacek Laskowski said:

Thank you!

 

I am already using that version of FastMM4 with the default options (I just checked, options fulldebugmode and AlwaysAllocateTopDown are set). 

 

But when I debug my program, compiled with {$SetPEFlags $0020}, it appears that allocated objects such as my main form still have addresses way below 2 GB.  Could it be that the {AlwaysAllocateTopDown} option isn't working in FastMM4 ?

Share this post


Link to post

Could you just allocate some memory (1-2 GB, probably in smaller chunks), so that other allocations have to be from the top part?

Share this post


Link to post
Guest

This

2 minutes ago, Vandrovnik said:

Could you just allocate some memory (1-2 GB, probably in smaller chunks), so that other allocations have to be from the top part?

Or

2) Cause a memory leak and see for your self that the reported address is bigger than $8000000.

3) Call VirtualAlloc manually requesting address's above $80000000.

Share this post


Link to post

I have a bad feeling about this.

 

When I perform a search (using Agent Ransack) for the string "Integer("  in the subdirectory where I keep my third-party libraries, I see lots and lots of places where pointers are being cast into signed 32-bit integers.  I see this especially in old libraries originally written by TurboPower, such as Abbrevia and Async Professional.  For example, the version of Abbrevia that can currently be downloaded using Getit for Delphi 10.4.1 contains the following line in unit AbCabTyp.pas (line 460):

  Result := Integer(TFileStream.Create(Archive.FIIPName, fmCreate))

 

This is just an example (my application does not use that particular unit) but these libraries are riddled with such gems.   Am I neurotic if I distrust such libraries in 32-bit code compiled with the large address space awareness flag ? 

 

Share this post


Link to post
25 minutes ago, A.M. Hoornweg said:

 


  Result := Integer(TFileStream.Create(Archive.FIIPName, fmCreate))

 

As long as it doesn't do "pointer math" on the integer value then there shouldn't be problems casting between integer and pointer.

  • Like 1

Share this post


Link to post
15 minutes ago, Anders Melander said:

As long as it doesn't do "pointer math" on the integer value then there shouldn't be problems casting between integer and pointer.

Wouldn't be the NativeInteger the right cast for a pointer ?

Matching the right bitness on 32- and 64-Bit machines, to the same pointer bitness ?

  • Like 1

Share this post


Link to post
16 minutes ago, Anders Melander said:

As long as it doesn't do "pointer math" on the integer value then there shouldn't be problems casting between integer and pointer.

This code is a problem when used in 64-bit version...

Share this post


Link to post

IMO, the > 2Gb 32-bit trick is an errorprone kludge. 

We are also dependent on 32-bit DLLs - but are considering going the extra length to isolate them behind an API of some sort.

Share this post


Link to post
1 minute ago, Rollo62 said:

Wouldn't be the NativeInteger the right cast for a pointer ?

Matching the right bitness on 32- and 64-Bit machines, to the same pointer bitness ?

 

2 minutes ago, Vandrovnik said:

This code is a problem when used in 64-bit version...

Dudes. I'm not stupid.

I'm not saying that it's good practice only that it's safe to cast between pointer and integer. The OP said that this was for 32-bit only so bringing 64-bit into the equation is also irrelevant.

 

Thanks for playing.

Share this post


Link to post
27 minutes ago, FPiette said:

Definitely not ! Use UIntPtr (Alias to NativeUInt) which is a type especially created for that purpose.

Yes, right.

type UIntPtr = NativeUInt;

 

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×