Steve Maughan 26 Posted January 9 I recently updated to D11.3 for AlignMix, our mapping solution. We were previously using D11.1. We have old code that reads a DBF file. This is used to read the DBF files associated with ESRI Shapefiles that contain geographic data. The code had worked for eight years without a problem. It still works in 32 bit mode but now doesn't work in 64 bit mode and gives an error. The DBF reading routine contains code that casts blocks of memory as strings etc — this is probably the root of the problem. If anyone is interested, I've attached a sample project that reads a DBF file using the code. In the sample project I only get two warnings: [dcc32 Warning] uDBF.pas(155): W1000 Symbol 'StrPas' is deprecated: 'Moved to the AnsiStrings unit' [dcc32 Warning] uDBF.pas(216): W1057 Implicit string cast from 'AnsiString' to 'string' Are these relevant? Question: what changed between D11.1 and D11.3 that could cause this type of problem? Was there any change involving casting of strings in 64 bit mode? All help appreciated! Steve DBF-64-Bit-Bug.zip Share this post Link to post
Attila Kovacs 629 Posted January 9 "Data" is not initialized in your demo GetMem(Data, iRecordLen); and that's it, it ponts to trash Share this post Link to post
Steve Maughan 26 Posted January 9 21 minutes ago, Attila Kovacs said: "Data" is not initialized in your demo GetMem(Data, iRecordLen); and that's it, it ponts to trash Thanks Attila, but I didn't think "Data" needed to be initialized. The GetMem function is asking the OS to allocate some memory of length "iRecord", and sets "Data" to point to the start of the allocated memory. Is this not correct? — Steve Share this post Link to post
Attila Kovacs 629 Posted January 9 (edited) 7 minutes ago, Steve Maughan said: Thanks Attila, but I didn't think "Data" needed to be initialized. The GetMem function is asking the OS to allocate some memory of length "iRecord", and sets "Data" to point to the start of the allocated memory. Is this not correct? — Steve Yes, but then you set up the fields' FData to point to there +iTmp and later you are trying to read the data from there, and AV raises. But if I'm wrong just ignore me, I had only a minute to look into it. Edited January 9 by Attila Kovacs 1 Share this post Link to post
Cristian Peța 103 Posted January 9 FData : DWORD; And should be 8 bytes on 64 bit. Something like PAnsiChar. Fields^[iFieldCount].FData := DWORD(Data + iTmp); It is wrong to cast to DWORD for 64 bit. 1 Share this post Link to post
Cristian Peța 103 Posted January 9 It is working like compiled in D11.1 if you disable ASLR from linking options. Share this post Link to post
Steve Maughan 26 Posted January 9 @Cristian Peța you found it!! When I disable the ASLR in Delphi 11.3 it also runs fine in 64 bit mode. That makes sense. MANY THANKS! Now the question is, how do I make it work with ASLR enabled. — Steve Share this post Link to post
Cristian Peța 103 Posted January 9 (edited) I used FieldData array to store offsets instead of FData that must remain 4 bytes. Maybe there are better approaches but it was faster so. This is a fast patch and not optimal. uDBF.pas Edited January 9 by Cristian Peța 1 Share this post Link to post
Steve Maughan 26 Posted January 9 Hi Cristian — many thanks but the file you uploaded is identical to the original. Is there a patched version? I owe you bigtime! — Steve Share this post Link to post
Cristian Peța 103 Posted January 9 (edited) Sorry, uploaded wrong file... uDBF.pas Edited January 9 by Cristian Peța Share this post Link to post
Cristian Peța 103 Posted January 9 Now I see that FieldData can be defined for max 256 fields. FieldData: array [0..255] of PAnsiChar; And get rid of setting the length of FieldData for every field. uDBF.pas 1 Share this post Link to post
Brian Evans 105 Posted January 9 1 hour ago, Steve Maughan said: @Cristian Peța you found it!! When I disable the ASLR in Delphi 11.3 it also runs fine in 64 bit mode. That makes sense. MANY THANKS! Now the question is, how do I make it work with ASLR enabled. — Steve It will crash if the top thirty-two bits of any pointer handled by the buggy code are not all zeroes. That just happens more often if ASLR is enabled or all the time if ASLR + the high entropy allocator is enabled. 1 Share this post Link to post
Steve Maughan 26 Posted January 9 @Cristian Peța this version works perfectly. Many thanks — I owe you one!! @Brian Evans Thanks — that makes sense. @Attila Kovacs thanks for the input! — Steve Share this post Link to post
Remy Lebeau 1395 Posted January 9 @Steve Maughan you might want to read: Converting 32-bit Delphi Applications to 64-bit Windows since the original code was doing things that were not meant to be done in 64bit builds to begin with. 1 Share this post Link to post
Steve Maughan 26 Posted January 9 Thanks @Remy Lebeau — I'll take a look. Share this post Link to post