Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2006-03

Re: FPC 2.0.0 vs FPC 2.0.2 (div by zero)

12 messages · 6 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Michalis Kamburelis
to Den Jean: I have a strange problem. My Qt4 demo program worked fine with FPC 2.0.0, but crashes…
Den Jean wrote 9 lines
Hi, I have a strange problem. My Qt4 demo program worked fine with FPC 2.0.0, but crashes (div by zero) with FPC 2.0.2. Debugging shows that indeed a div by zero is done within the Qt4 lib. However with FPC 2.0.0 or using C++ code the library isn't bothered with the div by zero. When I use FPC 2.0.2 however it is.

Maybe it was FPC 2.0.0 bug (that was fixed in the meantime) that caused this SIGFPE inside qt to be ignored ? AFAIK it was always the intention of FPC that if used library causes a signal like SIGFPE, this signal *will not be ignored* and will cause our program to fail with some exception.

Maybe you can workaround this with Set8087CW, just like it has to be workarounded for OpenGL under Windows (see
[http://www.freepascal.org/bugs/showrec.php3?ID=3955]). Just add "Set8087CW($133F);" at the beginning of your program (or even right inside qt unit initialization) and see if it helps.

(Note that I'm writing this without any knowledge of qt or your testcase --- I just thought that it may be helpful, sorry if it's not relevant :) ).

Michalis

Reply by email

Den Jean

Hi,

I have a strange problem. My Qt4 demo program worked fine with FPC 2.0.0, but crashes (div by zero) with FPC 2.0.2. Debugging shows that indeed a div by zero is done within the Qt4 lib. However with FPC 2.0.0 or using C++ code the library isn't bothered with the div by zero. When I use FPC 2.0.2 however it is.

I added some writelns euh printfs in the Qt lib:
 if (p1.x() == p2.x()) printf("Before DIV by Zero: p1.x:%f p2.x:
%f\n",p1.x(),p2.x());
edge.m = (p1.y() - p2.y()) / (p1.x() - p2.x()); // this causes the div by zero
if (p1.x() == p2.x()) printf("After DIV by Zero: p1.x:%f p2.x:
%f\n",p1.x(),p2.x());

with FPC 2.0.2 I get

Before DIV by Zero: p1.x:196.500000 p2.x:196.500000 An unhandled exception occurred at $405CB772 :
EDivByZero : Division by zero
$405CB772
etc

with FPC 2.0.0 or the original C++ demo program I get: Before DIV by Zero: p1.x:196.500000 p2.x:196.500000 After DIV by Zero: p1.x:196.500000 p2.x:196.500000 Before DIV by Zero: p1.x:187.500000 p2.x:187.500000 After DIV by Zero: p1.x:187.500000 p2.x:187.500000 Before DIV by Zero: p1.x:100.000000 p2.x:100.000000 After DIV by Zero: p1.x:100.000000 p2.x:100.000000 and so on, never a crash (but why :-)

Anyone any idea?

I uploaded everything to
(Qt libs, demo src code)
http://users.pandora.be/Jan.Van.hijfte/qtforfpc/demo_shapedclock_0.6.tar.gz

I compiled Qt 4.1.1 with debug info (hence the size of the tar) the file I added the printfs was
qt-x11-opensource-src-4.1.1/src/gui/painting/qpaintengine_x11.cpp

compile:
export LD_LIBRARTY_PATH=.
ppc386 -gl shapedclock.pas
./shapedclock

The program should look like this:
http://users.pandora.be/Jan.Van.hijfte/qtforfpc/shapedclock.png

Here is some gdb output
...
Qt: gdb: -nograb added to command-line options.
Use the -dograb option to enforce grabbing.
Before DIV by Zero: p1.x:196.500000 p2.x:196.500000

Program received signal SIGFPE, Arithmetic exception. [Switching to Thread 1087534720 (LWP 10897)]
0x405cb772 in qt_tesselate_polygon (traps=0xbf812e40, pg=0x8135b50, pgSize=9, winding=true)
at painting/qpaintengine_x11.cpp:361
361 edge.m = (p1.y() - p2.y()) / (p1.x() - p2.x()); // line derivative
Current language: auto; currently c++
(gdb) bt
#0 0x405cb772 in qt_tesselate_polygon (traps=0xbf812e40, pg=0x8135b50, pgSize=9, winding=true)
at painting/qpaintengine_x11.cpp:361
#1 0x405cca91 in QX11PaintEnginePrivate::fillPolygon_dev (this=0x81351e0, polygonPoints=0x81367c8,
pointCount=9, gcMode=QX11PaintEnginePrivate::PenGC, mode=QPaintEngine::WindingMode)
at painting/qpaintengine_x11.cpp:1533
#2 0x405cd050 in QX11PaintEnginePrivate::fillPath (this=0x81351e0, ,
gc_mode=QX11PaintEnginePrivate::PenGC, transform=false) at painting/qpaintengine_x11.cpp:1648
#3 0x405cd914 in QX11PaintEngine::drawPath (this=0x81309b8, ) at painting/qpaintengine_x11.cpp:1688
#4 0x405c41db in QX11PaintEngine::drawLines (this=0x81309b8, lines=0xbf8132cc, lineCount=1)
at painting/qpaintengine_x11.cpp:907
#5 0x4058285d in QPainter::drawLines (this=0x812e250, lines=0xbf8132cc, lineCount=1)
at painting/qpainter.cpp:3243
#6 0x400b7eef in QPainter::drawLine () from ./libqt4intf.so #7 0x4008f801 in QPainter_drawLine3 () from ./libqt4intf.so #8 0x080497cf in TCLOCK__PAINT (E=0xbf813848, this=0x812929c) at shapedclock.pas:164

kind regards,

Den Jean

Reply by email

Peter Vreman
to Den Jean
Show quoted text 35 lines
Hi, I have a strange problem. My Qt4 demo program worked fine with FPC 2.0.0, but crashes (div by zero) with FPC 2.0.2. Debugging shows that indeed a div by zero is done within the Qt4 lib. However with FPC 2.0.0 or using C++ code the library isn't bothered with the div by zero. When I use FPC 2.0.2 however it is. I added some writelns euh printfs in the Qt lib: if (p1.x() == p2.x()) printf("Before DIV by Zero: p1.x:%f p2.x: %f\n",p1.x(),p2.x()); edge.m = (p1.y() - p2.y()) / (p1.x() - p2.x()); // this causes the div by zero if (p1.x() == p2.x()) printf("After DIV by Zero: p1.x:%f p2.x: %f\n",p1.x(),p2.x()); with FPC 2.0.2 I get Before DIV by Zero: p1.x:196.500000 p2.x:196.500000 An unhandled exception occurred at $405CB772 : EDivByZero : Division by zero $405CB772 etc with FPC 2.0.0 or the original C++ demo program I get: Before DIV by Zero: p1.x:196.500000 p2.x:196.500000 After DIV by Zero: p1.x:196.500000 p2.x:196.500000 Before DIV by Zero: p1.x:187.500000 p2.x:187.500000 After DIV by Zero: p1.x:187.500000 p2.x:187.500000 Before DIV by Zero: p1.x:100.000000 p2.x:100.000000 After DIV by Zero: p1.x:100.000000 p2.x:100.000000 and so on, never a crash (but why :-) Anyone any idea?

In 2.0.0 the fpu exceptions are disabled if linking to C. In 2.0.2 this is fixed.

Reply by email

Den Jean
to Peter Vreman
Peter Vreman wrote
> Anyone any idea? In 2.0.0 the fpu exceptions are disabled if linking to C. In 2.0.2 this is fixed.

for "man G++ " it is not the default, I could not find Qt makefile to disable them, so I was a bit perplex.
(also had integer divisions in mind, quite a difference)

I notice now that even the smallest C++ program has FPE disabled
$ cat test.cpp
#include <stdio.h>
int main() { printf("FPE test:%f\n",142.0/0.0); }
$ ./a.out
FPE test:inf
So I now use fedisableexcept(FE_ALL_EXCEPT);
in the initialization section of qt4.pas

thx

Den Jean

Reply by email

Michalis Kamburelis
to Den Jean: I have a strange problem. My Qt4 demo program worked fine with FPC 2.0.0, but crashes…

(Second send, it seems that mails from my old email address do not reach fpc lists)

Den Jean wrote 9 lines
Hi, I have a strange problem. My Qt4 demo program worked fine with FPC 2.0.0, but crashes (div by zero) with FPC 2.0.2. Debugging shows that indeed a div by zero is done within the Qt4 lib. However with FPC 2.0.0 or using C++ code the library isn't bothered with the div by zero. When I use FPC 2.0.2 however it is.

Maybe it was FPC 2.0.0 bug (that was fixed in the meantime) that caused this SIGFPE inside qt to be ignored ? AFAIK it was always the intention of FPC that if used library causes a signal like SIGFPE, this signal *will not be ignored* and will cause our program to fail with some exception.

Maybe you can workaround this with Set8087CW, just like it has to be workarounded for OpenGL under Windows (see
[http://www.freepascal.org/bugs/showrec.php3?ID=3955]). Just add "Set8087CW($133F);" at the beginning of your program (or even right inside qt unit initialization) and see if it helps.

(Note that I'm writing this without any knowledge of qt or your testcase --- I just thought that it may be helpful, sorry if it's not relevant :) ).

Michalis

Reply by email

Den Jean
to Peter Vreman
Peter Vreman wrote 8 lines
> Hello, > > Is there a better way to disable fpu exception other then linking to > libc and calling fedisableexcept ??? Set8087CW() in system unit SetExceptionMask() in unit math

It was for MacOsX we needed to get rid of libc,
I guess Set8087CW($133F) is not CPU independant (PowerPC,x86_64), so I will use
Math.SetExceptionMask([exDenormalized,exInvalidOp,exOverflow,exPrecision,exUnderflow,exZeroDivide]);

I hope MacOsX is happier now (don't have one, so don't know)

kind regards,

Den Jean

Reply by email

Jose Manuel
to Den Jean
Show quoted text 5 lines
> Set8087CW() in system unit > SetExceptionMask() in unit math > It was for MacOsX we needed to get rid of libc, I guess Set8087CW($133F) is not CPU independant (PowerPC,x86_64),

AFAIK, x86_32 will do too!!

so I will use Math.SetExceptionMask([exDenormalized,exInvalidOp,exOverflow,e xPrecision,exUnderflow,exZeroDivide]);

I do agree it's much polite and cross platform, but doesn't seem to work in Windows XP Pro (only tested in WinXP Pro SP2) with GL 3.2 and FPC 2.0.2 (I've looked everywhere down my PC for a version number, but not found :-), I guess it oughtta be 4.1 but I can't stand for it). Anyway using Set8087CW (which is indeed CPU dependant) does work under my equipment, SetExceptionMask doesn't.

I hope MacOsX is happier now (don't have one, so don't know)

Just to make it know (as a primarily Win NT user). I really don't know whether it is as it should be or it should be fixed :-?. A plain Win user as me normally use syscalls to the API, but I'm afraid it's comprimising compatability issues. Masters will tell, I hope :-)

kind regards,

Regards,
JMR

Reply by email

Jonas Maebe
to Jose Manuel
Jose Manuel wrote 9 lines
> Math.SetExceptionMask([exDenormalized,exInvalidOp,exOverflow,e > xPrecision,exUnderflow,exZeroDivide]); I do agree it's much polite and cross platform, but doesn't seem to work in Windows XP Pro (only tested in WinXP Pro SP2) with GL 3.2 and FPC 2.0.2 (I've looked everywhere down my PC for a version number, but not found :-), I guess it oughtta be 4.1 but I can't stand for it). Anyway using Set8087CW (which is indeed CPU dependant) does work under my equipment, SetExceptionMask doesn't.

SetExceptionMask calls Set8087CW on x86, so if it doesn't work it's because you either use it wrongly, or because it translates its parameters wrongly to the input Set8087CW expects.

Jonas

Reply by email

Jose Manuel
to Jonas Maebe
>> Math.SetExceptionMask([exDenormalized,exInvalidOp,exOverflow,e >> xPrecision,exUnderflow,exZeroDivide]);

[...]

Show quoted text 6 lines
> stand for it). Anyway using Set8087CW (which is indeed CPU > dependant) does work under my equipment, SetExceptionMask doesn't. SetExceptionMask calls Set8087CW on x86, so if it doesn't work it's because you either use it wrongly, or because it translates its parameters wrongly to the input Set8087CW expects.

Maybe both :-)
I just was calling SetExceptionMask([exZeroDivide]), without qualifying. OK, thanks. I'll check it, and if I find anything odd in parameter translating I will tell. Anyway, don't pay me too much attention, I gotta review it all this weekend, but AFAICR I think I was using the DOS version under Windows XP (not a proper way of doing things ;-(). Sorry for the incoveniences and the loss of time. Anyhow I'll check it up.

Thanx,
JMR

Reply by email