Recent

Author Topic: Common File Dialogs Have Been Broken for a Very Long Time (Ex: Ubuntu AARCH64)  (Read 9446 times)

rvk

  • Hero Member
  • *****
  • Posts: 6572
What's the default of this snippet?

Code: Pascal  [Select][+][-]
  1. uses
  2.   ..., math,...
  3.  
  4. {...}
  5.  
  6. var
  7.   FPUException: TFPUException;
  8.   FPUExceptionMask: TFPUExceptionMask;
  9. begin
  10.   FPUExceptionMask := GetExceptionMask;
  11.   for FPUException := Low(TFPUException) to High(TFPUException) do begin
  12.     write(FPUException, ' - ');
  13.     if not (FPUException in FPUExceptionMask) then
  14.       write('not ');
  15.  
  16.     writeln('masked!');
  17.   end;
  18.   readln;
  19. end.

For me it's
Quote
exInvalidOp - not masked!
exDenormalized - masked!
exZeroDivide - not masked!
exOverflow - not masked!
exUnderflow - masked!
exPrecision - masked!
« Last Edit: November 06, 2024, 01:41:27 am by rvk »

TRon

  • Hero Member
  • *****
  • Posts: 3619
btw: Nice catch rvk.

laz 3.6
Code: Pascal  [Select][+][-]
  1. procedure TGtk2WidgetSet.AppInit(var ScreenInfo: TScreenInfo);
  2. begin
  3.   {$if defined(cpui386) or defined(cpux86_64)}
  4.   // needed otherwise some gtk theme engines crash with division by zero
  5.   {$IFNDEF DisableGtkDivZeroFix}
  6.     SetExceptionMask(GetExceptionMask + [exOverflow,exZeroDivide,exInvalidOp]);
  7.   {$ENDIF}
  8.   {$ifend}
  9. ...
  10. end;
  11.  
This tagline is powered by AI (AI advertisement: Free Pascal the only programming language that matters)

rvk

  • Hero Member
  • *****
  • Posts: 6572
I can do anything with SetExceptionMask. No combination will fail for me.

That makes me believe the problem is in the specific gtk2 framework or its interaction and combination with parallels. That is the one that generates a SIGFPE. For the gtk2 framework this is suppressed in FPC/Lazarus on intel architecture ( to not show any exception inside the GUI) because FPC/Lazarus can't fix this. So it's just a programmer problem in the GUI.

Seeing the {$if defined(cpui386) or defined(cpux86_64)} in that TGtk2WidgetSet.AppInit... I guess they forgot aarch64  :D

@msintle Does adding this line work? In that case the if defined line can just be expanded to include the arm-platform.
Code: Pascal  [Select][+][-]
  1. SetExceptionMask(GetExceptionMask + [exOverflow,exZeroDivide,exInvalidOp]);

BUT... I wonder if this is the correct way...
I haven't tested this but doesn't the above line also prevent your own division by zero etc.????
Is that wanted behavior?

Shouldn't the SetExceptionMask not ONLY be done when calling a certain widget-set call, and reset it directly after, so errors in your own program get catched by your own exception handling?

rvk

  • Hero Member
  • *****
  • Posts: 6572
Apparently for gtk3 and the qt5 etc. the SetExceptionMask is always done on all exceptions. No define for intel there.
For gtk2 it's only done for cpui386 and cpux86_64.

gtk3object.inc
Code: Pascal  [Select][+][-]
  1. constructor TGtk3WidgetSet.Create;
  2. var
  3.   AValue: TGValue;
  4.   i: Integer;
  5. begin
  6.   SetExceptionMask([exInvalidOp, exDenormalized, exZeroDivide, exOverflow, exUnderflow, exPrecision]);
  7.   inherited Create;

qt5.pas
Code: Pascal  [Select][+][-]
  1. initialization
  2. //...
  3. SetExceptionMask([exDenormalized,exInvalidOp,exOverflow,exPrecision,exUnderflow,exZeroDivide]);
  4. end.

« Last Edit: November 06, 2024, 10:53:25 am by rvk »

Thaddy

  • Hero Member
  • *****
  • Posts: 16139
  • Censorship about opinions does not belong here.
Rik, what is exInvalidOp doing there? Does not make sense at all. That is a bug and not related to this.
For AARCH64 just the underflow and overflow need to be masked, possibly only underflow but I need to test that.
The ratio behind this remark is that masking exceptions should not be the rule, but the exception. AARCH64 has some known issues over all implementations of the hardware, not fpc: the M series behaves just as bad as the Raspberry pi's.
« Last Edit: November 06, 2024, 11:03:01 am by Thaddy »
If I smell bad code it usually is bad code and that includes my own code.

rvk

  • Hero Member
  • *****
  • Posts: 6572
Rik, what is exInvalidOp doing there? Does not make sense at all. That is a bug and not related to this.
Apparently the EInvalidOp gets raised when zero is divided by zero.

If the framework does something like that internally (no idea why it should but it seems to happen) you need to mask that exception.
I think that's the reason it was put in by the core-developers.

Quote
Normally, dividing non-zero value by zero raises EZeroDivide exception and dividing zero by zero raises EInvalidOp.
https://wiki.freepascal.org/Multiplatform_Programming_Guide#Gtk2_and_masking_FPU_exceptions

Thaddy

  • Hero Member
  • *****
  • Posts: 16139
  • Censorship about opinions does not belong here.
The latter IS a bug in fpc, because it should raise EDivisionByZero. I will try and test it.
But do not mask out everything unless you know what you are masking.
I believe Jonas made a similar remark a couple of years ago.
« Last Edit: November 06, 2024, 11:07:00 am by Thaddy »
If I smell bad code it usually is bad code and that includes my own code.

rvk

  • Hero Member
  • *****
  • Posts: 6572
The latter IS a bug in fpc, because it should raise EDivisionByZero. I will try and test it.
But do not mask out everything unless you know what you are masking.
I believe Jonas made a similar remark a couple of years ago.
On Delphi 0 / 0 also generates a 'Floating point invalid operation' (EInvalidOP).
Any other number divided by 0 will give a 'Floating point divide by 0' (EDivisionByZero).

So changing that would deviate from Delphi.

I agree that masking such exception isn't a particular good idea. But I guess this is done because of some problems in the gtk2 and qt5 frameworks. Like this topic shows a SIGFPE is generated by gtk2. Masking that will fix it. Maybe in some situation the framework also generates EInvalidOP etc at random points. There is nothing in FPC you can do about it other than masking it. But you can go ahead and discus this with the core developers to change it.


msintle

  • Full Member
  • ***
  • Posts: 233
That makes me believe the problem is in the specific gtk2 framework or its interaction and combination with parallels.

Please trust me on this, it has nothing to do with Parallels. I already ran a test for you guys with VMware, and the issue reproduced there perfectly as well.

msintle

  • Full Member
  • ***
  • Posts: 233
btw: Nice catch rvk.

laz 3.6
Code: Pascal  [Select][+][-]
  1. procedure TGtk2WidgetSet.AppInit(var ScreenInfo: TScreenInfo);
  2. begin
  3.   {$if defined(cpui386) or defined(cpux86_64)}
  4.   // needed otherwise some gtk theme engines crash with division by zero
  5.   {$IFNDEF DisableGtkDivZeroFix}
  6.     SetExceptionMask(GetExceptionMask + [exOverflow,exZeroDivide,exInvalidOp]);
  7.   {$ENDIF}
  8.   {$ifend}
  9. ...
  10. end;
  11.  

Thank you all for finally resolving this issue!

This fits in consistently with all of my findings - that the issue happens only on aarch64, that it has nothing to do with virtualization, that it has been there for ever, etc.

TRon

  • Hero Member
  • *****
  • Posts: 3619
Still, at the same time I do not seem to have any issue with running on and with gtk2 on a Pi.

I have tried to delve deeper into the subject parallels and discovered that some games refuse to run and produce a "invalid FPU mode", depending on parallels settings (hybrid vs strict execution and with/without admin rights) though this seems (emulating) windows related. I do not know parallels so perhaps worth a shot (can only become a misfire :-) ).

The setexpceptionmask workaround seems easier.

@msintle:
You're welcome but actually it is rvk that provided the (most) important clue.
« Last Edit: November 06, 2024, 11:21:29 am by TRon »
This tagline is powered by AI (AI advertisement: Free Pascal the only programming language that matters)

Thaddy

  • Hero Member
  • *****
  • Posts: 16139
  • Censorship about opinions does not belong here.
On Delphi 0 / 0 also generates a 'Floating point invalid operation' (EInvalidOP).
No, Delphi reports it as NaN and at runtime.
Code: Pascal  [Select][+][-]
  1. program Project1;
  2. {$APPTYPE CONSOLE}
  3. begin
  4.   writeln (0/0);
  5.   readln;
  6. end.
Tested D7 and 12.2.
« Last Edit: November 07, 2024, 07:35:36 pm by Thaddy »
If I smell bad code it usually is bad code and that includes my own code.

rvk

  • Hero Member
  • *****
  • Posts: 6572
Code: [Select]
[quote author=rvk link=topic=68845.msg537079#msg537079 date=1730887943]
On Delphi 0 / 0 also generates a 'Floating point invalid operation' (EInvalidOP).
[/quote]
 No, Delphi reports it as NaN and at runtime.
[coode=pascal]program Project1;
{$APPTYPE CONSOLE}
begin
  writeln (0/0);
  readln;
end.
Tested D7 and 12.2.
Try this example on Delphi. I'm sure it will generate a EInvalidOp:

Quote
Project Project1.exe raised exception class EInvalidOp with message 'Invalid floating point operation at address 0040C10E'.

Code: Pascal  [Select][+][-]
  1. program Project1;
  2. {$APPTYPE CONSOLE}
  3. var
  4.   I: Integer;
  5.   F: Double;
  6. begin
  7.   I := 0;
  8.   F := I / I;
  9.   writeln (F);
  10.   readln;
  11. end.

msintle

  • Full Member
  • ***
  • Posts: 233
Do we know yet why this report never reproduced on pi?

rvk

  • Hero Member
  • *****
  • Posts: 6572
Do we know yet why this report never reproduced on pi?
That's deep in gtk2 (where the SIGFPE occurs).
This could be due to a lot of (internal) factors.

My current version is debian version for pi is 12.2 but I should be able to trash that pi soon (and can experiment on it).

 

TinyPortal © 2005-2018