Lazarus

Free Pascal => Windows => Topic started by: JernejL on November 07, 2019, 06:08:34 pm

Title: cannot use a certain dll under freepascal, but works with delphi- cdecl problem?
Post by: JernejL on November 07, 2019, 06:08:34 pm
i've compiled libsquish to a 32 bit dll a long time ago, the dll is rather simple and works well in delphi 7
 
It is a very simple and quality library, which compresses raw graphics to DXT compression and back.
 
however i get the same code and dll to crash under freepascal,
 
Quote
[Window Title]
Error

[Content]
Project TexWorkshop raised exception class 'External: ?'.

 At address 72D1117A

[OK]



Code: Pascal  [Select][+][-]
  1.  
  2. {
  3. http://code.google.com/p/libsquish/source/browse/trunk/squish.h
  4.  
  5. void CompressImage( u8 const* rgba, int width, int height, void* blocks, int flags, float* metric = 0 );
  6. void DecompressImage( u8* rgba, int width, int height, void const* blocks, int flags );
  7. int GetStorageRequirements( int width, int height, int flags );
  8. }
  9.  
  10. const
  11.  
  12.         //! Use DXT1 compression.
  13.         kDxt1 = 1 shl 0;
  14.         //! Use DXT3 compression.
  15.         kDxt3 = ( 1 shl 1 );
  16.         //! Use DXT5 compression.
  17.         kDxt5 = ( 1 shl 2 );
  18.         //! Use a very slow but very high quality colour compressor.
  19.         kColourIterativeClusterFit = ( 1 shl 8 );
  20.         //! Use a slow but high quality colour compressor (the default).
  21.         kColourClusterFit = ( 1 shl 3 );
  22.         //! Use a fast but low quality colour compressor.
  23.         kColourRangeFit = ( 1 shl 4 );
  24.         //! Use a perceptual metric for colour error (the default).
  25.         kColourMetricPerceptual = ( 1 shl 5 );
  26.         //! Use a uniform metric for colour error.
  27.         kColourMetricUniform = ( 1 shl 6 );
  28.         //! Weight the colour by alpha during cluster fit (disabled by default).
  29.         kWeightColourByAlpha = ( 1 shl 7 );
  30.  
  31. procedure CompressImage( rgba: Pu8; width, height: integer; blocks: pointer; flags: integer; metric: psingle ); cdecl; external 'libsquish.dll';
  32. procedure DecompressImage( rgba: pointer; width, height: integer; blocks: pointer; flags: integer ); cdecl; external 'libsquish.dll';
  33. function GetStorageRequirements( width, height, flags: integer): integer; cdecl; external 'libsquish.dll';
  34.  
  35.  

Whole call stack is following:
 
Code: Pascal  [Select][+][-]
  1. #0 ?? at :0
  2. #1 squish!CompressImage at :0
  3. #2 squish!CompressImage at :0
  4. #3 squish!DecompressImage at :0
  5. #4 squish!CompressImage at :0
  6. #5 COMPRESSDXTIMAGE(true, 3, 0x26c4b80, 0x26d67c0) at u_workshop.pas:1653
  7. #6 BTN_PROPERTIESCLICK(0x26ed678, 0x26efc08) at u_workshop.pas:1305
  8. #7 CONTROLS$_$TCONTROL_$__$$_DBLCLICK at :0
  9. #8 CONTROLS$_$TCONTROL_$__$$_WMLBUTTONDBLCLK$TLMMOUSE at :0
  10. #9 SYSTEM$_$TOBJECT_$__$$_DISPATCH$formal at :0
  11. #10 VMT_$CONTROLS_$$_TCONTROL at :0
  12. #11 ?? at :0
  13. #12 ?? at :0
  14. #13 ?? at :0
  15. #14 CONTROLS$_$TWINCONTROL_$__$$_WNDPROC$TMESSAGE at :0
  16. #15 LCLMESSAGEGLUE_$$_DELIVERMESSAGE$TOBJECT$formal$$LONGINT at :0
  17. #16 WIN32INT$_$TWINDOWPROCHELPER_$__$$_DOWINDOWPROC$$LONGINT at :0
  18. #17 WIN32INT_$$_WINDOWPROC$LONGWORD$LONGWORD$LONGINT$LONGINT$$LONGINT at :0
  19. #18 WIN32WSSTDCTRLS_$$_LISTBOXWINDOWPROC$LONGWORD$LONGWORD$LONGINT$LONGINT$$LONGINT at :0
  20. #19 USER32!AddClipboardFormatListener at :0
  21. #20 USER32!CallWindowProcW at :0
  22. #21 USER32!DispatchMessageW at :0
  23. #22 USER32!DispatchMessageW at :0
  24. #23 WIN32INT$_$TWIN32WIDGETSET_$__$$_APPPROCESSMESSAGES at :0
  25. #24 FORMS$_$TAPPLICATION_$__$$_HANDLEMESSAGE at :0
  26. #25 FORMS$_$TAPPLICATION_$__$$_RUNLOOP at :0
  27. #26 INTERFACEBASE$_$TWIDGETSET_$__$$_APPRUN$TAPPLICATIONMAINLOOP at :0
  28. #27 FORMS$_$TAPPLICATION_$__$$_RUN at :0
  29. #28 main at TexWorkshop.dpr:24
  30.  

There is not much to analyse, as the whole thing makes no sense - a c++ dll with cdecl calls should behave identically in both cases? Does anybody know what could cause this?
 
Title: Re: cannot use a certain dll under freepascal, but works with delphi- cdecl problem?
Post by: 440bx on November 07, 2019, 06:40:56 pm
I don't know if the following may be applicable to your case but, just in case, check the following thread https://forum.lazarus.freepascal.org/index.php?topic=6225.0
Title: Re: cannot use a certain dll under freepascal, but works with delphi- cdecl problem?
Post by: Thaddy on November 07, 2019, 06:45:01 pm
Try 3.2.0 because it has structured exception handling as default for win32.
Title: Re: cannot use a certain dll under freepascal, but works with delphi- cdecl problem?
Post by: julkas on November 07, 2019, 07:27:51 pm
Give more info about OS, FPC / Lazarus. Attach library.
Are you using mode Delphi?
Title: Re: cannot use a certain dll under freepascal, but works with delphi- cdecl problem?
Post by: marcov on November 07, 2019, 10:40:29 pm
Try 3.2.0 because it has structured exception handling as default for win32.

Not yet. It needs a define to activate. But yes, this could be the cause.
Title: Re: cannot use a certain dll under freepascal, but works with delphi- cdecl problem?
Post by: JernejL on November 08, 2019, 08:51:25 am
I've attached the dll, i use fpc 3.0.4 with lazarus 2.0.0 - compiled on windows for win32 api.
Regarding the debugger, crash happens also when ran without debugger.
 
The squish dll is simple - just point the source and dest to a large enough buffers, the input can be garbage too, for example call compress on random memory stream data (each pixel is 4 bytes), and have output same size buffer.
 
Here is an example call, with the dll i attached:
 
Code: Pascal  [Select][+][-]
  1.  
  2. procedure Twnd_workshop.btn1Click(Sender: TObject);
  3. const
  4.         iwidth = 128;
  5.         iheight = 128;
  6. var
  7.         inimage: Tmemorystream;
  8.         datastream: Tmemorystream;
  9.         gsr: integer;
  10. begin
  11.  
  12.  
  13.         inimage:= TMemoryStream.Create();
  14.         inimage.Size:= (iwidth * iheight) * 4;
  15.        
  16.         gsr:= GetStorageRequirements(iwidth, iheight, kDxt3 or kColourIterativeClusterFit);
  17.  
  18.         datastream:= TMemoryStream.Create(); // output stream
  19.         datastream.Size:= gsr;
  20.  
  21.         CompressImage(inimage.memory, iwidth, iheight, datastream.Memory, kDxt3 or kColourIterativeClusterFit, nil);
  22.        
  23. end;
  24.  
  25.  

This will work perfectly in delphi 7, but crash very strangely if compiled with freepascal.
 
Title: Re: cannot use a certain dll under freepascal, but works with delphi- cdecl problem?
Post by: Thaddy on November 08, 2019, 08:57:01 am
Can you test as per my suggestion and Marco's remark?
Otherwise I need full sources that replicate the issue.
Title: Re: cannot use a certain dll under freepascal, but works with delphi- cdecl problem?
Post by: JernejL on November 08, 2019, 09:06:38 am
Can you test as per my suggestion and Marco's remark?
Otherwise I need full sources that replicate the issue.

 
You need only the dll i attached in zip file and the example code i posted - compile with win32 and it will crash on compress line.
 
Regarding SEH, it could be - i would need to custom compile the compile, can someone first check if SEH is the issue?
 
I don't think this is SEH fault tho - there is no exception at all under delphi.
 
Title: Re: cannot use a certain dll under freepascal, but works with delphi- cdecl problem?
Post by: julkas on November 08, 2019, 09:28:47 am
Can you test as per my suggestion and Marco's remark?
Otherwise I need full sources that replicate the issue.

 
You need only the dll i attached in zip file and the example code i posted - compile with win32 and it will crash on compress line.
 
Regarding SEH, it could be - i would need to custom compile the compile, can someone first check if SEH is the issue?
 
I don't think this is SEH fault tho - there is no exception at all under delphi.

Try attached project. It works for me (Win8 64bit, FPC 3.0.4 / Lazarus 2.0.0) compiled for Win32.
Title: Re: cannot use a certain dll under freepascal, but works with delphi- cdecl problem?
Post by: JernejL on November 08, 2019, 10:07:54 am
I found something - i ran the tool in visual studio and got a better exception message:
 
Quote
Unhandled exception at 0x6D0C4815 (squish.dll) in TexWorkshop.exe: 0xC00002B5:  Multiple floating point traps (parameters: 0x00000000, 0x00001921).

I've added a call to Math.SetExceptionMask and exceptions disappeared.. i'm not aware that delphi 7 version of the app changed this in any way, but it happened somehow?! it's possible that i had something else included in some way that messed with this in delphi 7 version..
 
Oh well - at least i can say that libsquish works well in fpc and i've ported my last game tool to 100% lazarus + FPC development
 
Title: Re: cannot use a certain dll under freepascal, but works with delphi- cdecl problem?
Post by: Thaddy on November 08, 2019, 10:12:12 am

I don't think this is SEH fault tho - there is no exception at all under delphi.
Delphi doesn't know anything else, so that is why that is important.
And yes, specifically ms compilers mess with the float settings.(and are not in any way compliant to standards)
Glad it is now solved.
Title: Re: cannot use a certain dll under freepascal, but works with delphi- cdecl problem?
Post by: 440bx on November 08, 2019, 11:12:58 am
i ran the tool in visual studio and got a better exception message:
It's nice to see that alternate way of debugging is used and useful :)
Title: Re: cannot use a certain dll under freepascal, but works with delphi- cdecl problem?
Post by: JernejL on November 08, 2019, 11:40:43 am
i ran the tool in visual studio and got a better exception message:
It's nice to see that alternate way of debugging is used and useful :)

I actually do this regularly because i link to a bunch of c++ libraries in my game.
 
I compile program with dwarf debug symbols and use https://github.com/rainers/cv2pdb that converts the debug sybols to PDB file.
Then i run program and attach debugger in visual studio 2013 - it can then debug all used c++ dlls and main program loaded easily, it also shows pascal files in editor - breakpoints, call stack, function names and even profiling - it all works.
 
Title: Re: cannot use a certain dll under freepascal, but works with delphi- cdecl problem?
Post by: PascalDragon on November 09, 2019, 10:57:27 am

I don't think this is SEH fault tho - there is no exception at all under delphi.
Delphi doesn't know anything else, so that is why that is important.
And yes, specifically ms compilers mess with the float settings.(and are not in any way compliant to standards)
Glad it is now solved.
That has nothing to do with MS compilers. It would be similar with GCC: C/C++ programs normally don't expect floating point exceptions (floating point exceptions are not part of the standard). FPC (and Delphi) by default set the exception mask to something different, so it is rather common that one has to change the exception mask when working with such libraries.
Title: Re: cannot use a certain dll under freepascal, but works with delphi- cdecl problem?
Post by: Thaddy on November 09, 2019, 11:32:13 am

I don't think this is SEH fault tho - there is no exception at all under delphi.
Delphi doesn't know anything else, so that is why that is important.
And yes, specifically ms compilers mess with the float settings.(and are not in any way compliant to standards)
Glad it is now solved.
That has nothing to do with MS compilers. It would be similar with GCC: C/C++ programs normally don't expect floating point exceptions (floating point exceptions are not part of the standard). FPC (and Delphi) by default set the exception mask to something different, so it is rather common that one has to change the exception mask when working with such libraries.
It is actually that the Borland 32 bit compilers - including C++ builder - adhere to the IEEE 754 described standards for floating point handling, whereas msvc does not adhere. if other compilers follow msvc they are also not standards compliant.
But indeed the issue exists for many years and up until now I only have to solve it for ms compiled code, or recompile for C++ builder (which I do not recommend for 32 bit since it optimizes not as good as msvc.) Danny Thorpe wrote a lengthy blog about this many moons ago. I'll see if I can find it.
Title: Re: cannot use a certain dll under freepascal, but works with delphi- cdecl problem?
Post by: valdir.marcos on November 09, 2019, 02:18:20 pm

I don't think this is SEH fault tho - there is no exception at all under delphi.
Delphi doesn't know anything else, so that is why that is important.
And yes, specifically ms compilers mess with the float settings.(and are not in any way compliant to standards)
Glad it is now solved.
That has nothing to do with MS compilers. It would be similar with GCC: C/C++ programs normally don't expect floating point exceptions (floating point exceptions are not part of the standard). FPC (and Delphi) by default set the exception mask to something different, so it is rather common that one has to change the exception mask when working with such libraries.
It is actually that the Borland 32 bit compilers - including C++ builder - adhere to the IEEE 754 described standards for floating point handling, whereas msvc does not adhere. if other compilers follow msvc they are also not standards compliant.
But indeed the issue exists for many years and up until now I only have to solve it for ms compiled code, or recompile for C++ builder (which I do not recommend for 32 bit since it optimizes not as good as msvc.)
Danny Thorpe wrote a lengthy blog about this many moons ago. I'll see if I can find it.
Is it this one?
PC Mag, 22 feb 1994, PowerProgramming, Danny Thorpe, Senior Quality-Assurance Engineer for the Pascal Development Team at Borland International  in 1980's and 1990's.
https://books.google.com.br/books?id=v5YwX3auv0cC&pg=PA284&lpg=PA284&dq=Danny+Thorpe++floating-point+operations&source=bl&ots=8ju2aRzoc5&sig=ACfU3U2esJskwOHoUkfHXMES_KnHXPSdCw&hl=pt-BR&sa=X&ved=2ahUKEwi-y4_Wg93lAhU3ILkGHVC2CMkQ6AEwAXoECAkQAQ#v=onepage&q=Danny%20Thorpe%20%20floating-point%20operations&f=false

Or is it here?
Delphi Compiler Core blog (2003-2005) Added to Archives
Posted by Danny Thorpe at 12:02 am Sep 14, 2012
https://dannythorpe.com/2012/09/14/delphi-compiler-core-blog-2003-2005-added-to-archives/
Title: Re: cannot use a certain dll under freepascal, but works with delphi- cdecl problem?
Post by: Thaddy on November 09, 2019, 03:08:47 pm
Neither. It should be somewhere around 1997-8. He wrote specifically about interfacing with non-IEEE 754 compliant dll's, specifically msvc and  Delphi32.
Title: Re: cannot use a certain dll under freepascal, but works with delphi- cdecl problem?
Post by: JernejL on November 09, 2019, 03:22:32 pm
Interesting how this floating point stuff is not so uniform at all.
 
It does bother me that the exception information in fpc and lazarus debugger in this case was very useless,
 
Visual studio said "Multiple floating point traps (parameters: 0x00000000, 0x00001921)."
 
FPC/Lazarus: "Project TexWorkshop raised exception class 'External: ?'. At address 72D1117A"
 
Could this be a good example for a bug report / improvement?
 
Title: Re: cannot use a certain dll under freepascal, but works with delphi- cdecl problem?
Post by: Thaddy on November 09, 2019, 03:25:14 pm
Different compilers compile different code and to different addresses, so that is not a bug  by itself.
Title: Re: cannot use a certain dll under freepascal, but works with delphi- cdecl problem?
Post by: 440bx on November 09, 2019, 05:42:58 pm
Could this be a good example for a bug report / improvement?
I agree that there is definitely room for the message to be improved.  Personally, I think it is worth reporting.  Reporting it will make it visible and give the FPC developers the opportunity to decide if they want to do something about it.
Title: Re: cannot use a certain dll under freepascal, but works with delphi- cdecl problem?
Post by: JernejL on November 09, 2019, 08:01:01 pm
Different compilers compile different code and to different addresses, so that is not a bug  by itself.

This is not a matter of code, but debugging - debugger in visual studio made a more correct error message than gdb + lazarus debugging combo, debugged were identical binaries.
 
Title: Re: cannot use a certain dll under freepascal, but works with delphi- cdecl problem?
Post by: valdir.marcos on December 19, 2019, 08:40:42 am
Could this be a good example for a bug report / improvement?
I agree that there is definitely room for the message to be improved.  Personally, I think it is worth reporting.  Reporting it will make it visible and give the FPC developers the opportunity to decide if they want to do something about it.
Different compilers compile different code and to different addresses, so that is not a bug  by itself.
This is not a matter of code, but debugging - debugger in visual studio made a more correct error message than gdb + lazarus debugging combo, debugged were identical binaries.
It seems that, in the future, GDB will be deprecated and abandoned in favor of fpDebug.
Maybe this bug report should be better addressed to improve fpDebug.
TinyPortal © 2005-2018