Jump to content
Sign in to follow this  

Access Violation when optimization is on

Recommended Posts

The following function raises an Access Violation when compiled with Delphi 2007 with optimization turned on, but works fine with optimization turned off:

function TryInterlockedMask(var _Destination: LongWord; _AndMask, _OrMask: LongWord): Boolean;
  OldValue: LongWord;
  NewValue: LongWord;
  CurValue: LongWord;
  Assert(IsAlignedOn32bitBoundary(@_Destination), 'Destination is not aligned to a 32 bit boundary');
  OldValue := _Destination;
  NewValue := OldValue and _AndMask or _OrMask;
  CurValue := InterlockedCompareExchange(_Destination, NewValue, OldValue);
  Result := (OldValue = CurValue);

Can you see any problems with it?


It has been used for many years in a program which was always compiled with debug settings where optimization was turned turned off. Now I have created release settings for the project with optimization turned on (and changed some other compiler options but I verified that it is optimization that causes the problem) and all of a sudden it bombed out.

After turning optimization off for this function only, it works fine again.

Share this post

Link to post
54 minutes ago, dummzeuch said:

Can you see any problems with it?

It seem OK.


But as Uwe suggested it will be nice to confirm the assembly match.


I think you should track that _Destination origin at the caller and most likely it is a field in a record, by default record should not act like that unless packed identifier had been used, and here it might be accompanied with DEBUG conditional directive, so my suggestion is track the source caller and find that field then check the unit file for forgotten compiler directive that affecting the field align width, and of course in case it affect the memory usage greatly then all what you need is shuffle that record fields to make sure that field in question is aligned or add a NotUsed padding field.

Share this post

Link to post

It's going to be alignment of the local variables. They need to be aligned. You probably need to allocate an array with 12 bytes in (well, 11 will do), and do some bit twiddling to get the addresses within that array that are aligned.


EDIT: Actually, I'm not sure of that now. I guess the two by value params are passed on the stack so I'm probably talking rubbish.

Edited by David Heffernan

Share this post

Link to post
1 hour ago, Kas Ob. said:

I think you should track that _Destination origin at the caller and most likely it is a field in a record

No, it's a (actually the only) field in an object, so it should always be 32 bits aligned. Also, the assertion in the code checks for that condition and was active in all my tests and never failed.

Edited by dummzeuch

Share this post

Link to post
2 hours ago, Uwe Raabe said:

Did you compare the generated op code?

No, not yet.

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
Sign in to follow this