August 20, 2011

Arthelion Arthelion
Lab Rat
2 posts

QProgressDialog FPE exception

 

Hi
I’ve got a strange problem with QProgressDialog, the following example raises a Floating Point Exception where indicated, on Windows XP SP3 / Qt 4.7.3.
If I add 1 to the setValue, or subtract 1 to the start value, or run just the second loop, or use 2 different panels for each loop, it works.
I’ve tried to add a “reset”, before the second loop, it also crashes.
Does someone know what’s wrong there ?
Thanks

  1. #include <QtGui/QApplication>
  2. #include <QProgressDialog>
  3. #include <windows.h>
  4.  
  5. int main(int argc, char *argv[])
  6. {
  7.     QApplication a(argc, argv);
  8.  
  9.     QProgressDialog aProgress;
  10.     aProgress.setAutoClose(false);
  11.     aProgress.show();
  12.  
  13.     // Loop 1
  14.     aProgress.setRange(0,65538);
  15.     aProgress.setValue(0);
  16.     Sleep(1000);
  17.     aProgress.setValue(30000);
  18.     Sleep(1000);
  19.     aProgress.setValue(65538);
  20.     Sleep(1000);
  21.  
  22.     // Loop 2
  23.     aProgress.setRange(78640,1862200);
  24.     aProgress.setValue(78640); // ===> Crash !! SIGFPE
  25.     // aProgress.setValue(78641); // This one would not crash !!
  26.     Sleep(1000);
  27.     aProgress.setValue(1200000);
  28.     Sleep(1000);
  29.     aProgress.setValue(1862200);
  30.     Sleep(1000);
  31.  
  32.     return 0;
  33. }

6 replies

August 20, 2011

sierdzio sierdzio
Area 51 Engineer
2322 posts

Why windows.h? Try more Qt :P

Onto the subject: after modifying the code somewhat (removing windows.h… since I use Linux), I can confirm, it did crash ONCE. I then tried a few configurations (no crashes), and came back to the initial, “unstable” setting. It worked. Quite mystifying. I would imagine it has something to do with floats “floating” conversion around 78640, which may occasionally give different result than setRange – but to be honest, I’ve got no idea. Yet.

It also crashed once in debug, all on Qt 4.8. No crashes on 4.7.3.

 Signature 

(Z(:^

August 20, 2011

Lukas Geyer Lukas Geyer
Gene Splicer
2074 posts

I can reproduce the problem but I’m not quite sure if this can be seen as a bug (further investigation required). What I can tell you is that the documentation explicitly states

QProgressDialog [doc.qt.nokia.com] For the progress dialog to work as expected, you should initially set this property to 0 and finally set it to QProgressDialog::maximum(); you can call setValue() any number of times in-between.

Adding aProgress.setValue(0) before line #24 will solve your problem.

  1. void QProgressDialog::setValue(int progress)
  2. {
  3.     // ...
  4.         if (progress == 0) {
  5.             d->starttime.start();
  6.             d->forceTimer->start(d->showTime);
  7.             return;
  8.         } else {
  9.             bool need_show;
  10.             int elapsed = d->starttime.elapsed();
  11.             if (elapsed >= d->showTime) {
  12.                 need_show = true;
  13.             } else {
  14.                 if (elapsed > minWaitTime) {
  15.                     int estimate;
  16.                     int totalSteps = maximum() - minimum();
  17.                     int myprogress = progress - minimum(); // 78640 - 78640 = 0
  18.                     if ((totalSteps - myprogress) >= INT_MAX / elapsed)
  19.                         estimate = (totalSteps - myprogress) / myprogress * elapsed; // division by zero
  20.                     else
  21.                         estimate = elapsed * (totalSteps - myprogress) / myprogress;
  22.                     need_show = estimate >= d->showTime;
  23.                 } else {
  24.                     need_show = false;
  25.                 }
  26.             }
  27.     // ...

August 20, 2011

Lukas Geyer Lukas Geyer
Gene Splicer
2074 posts
sierdzio wrote:
… I would imagine it has something to do with floats “floating” conversion around 78640, which may occasionally give different result than setRange …

SIGFPE or floating point exception is quite misleading here. It is used to signal any erroneous arithmetic operation like FPE_INTDIV – division by zero – in this case.

August 20, 2011

sierdzio sierdzio
Area 51 Engineer
2322 posts
Lukas Geyer wrote:
sierdzio wrote:
… I would imagine it has something to do with floats “floating” conversion around 78640, which may occasionally give different result than setRange …

SIGFPE or floating point exception is quite misleading here. It is used to signal any erroneous arithmetic operation like FPE_INTDIV – division by zero – in this case.

Yeah, I wanted to make that point, too, but it crashed just once for me, so did not have the chance to investigate the crash itself, hence my jumping to other conclusion. And I was too lazy to check QProgressDialog code. As you rightfully pointed out, though, QPD’s source makes the origin of this error pretty clear. Thanks :)

// Now I think about it, those are all ints in this code… damn! The “floating point” eluded me so much it made me believe we’re discussing floats. Shame on me.

 Signature 

(Z(:^

August 20, 2011

Arthelion Arthelion
Lab Rat
2 posts

sierdzio wrote:
Why windows.h? Try more Qt :P

You’re right… I was too lazy to search for the Qt one (I never use Sleep in “real” code, that was just for the test).

Lukas Geyer wrote:
I can reproduce the problem but I’m not quite sure if this can be seen as a bug (further investigation required). What I can tell you is that the documentation explicitly states

QProgressDialog [doc.qt.nokia.com] For the progress dialog to work as expected, you should initially set this property to 0 and finally set it to QProgressDialog::maximum(); you can call setValue() any number of times in-between.

Adding aProgress.setValue(0) before line #24 will solve your problem.


Sorry, I didn’t notice that point in the doc. It’s at least really tricky to allow some min value but assume the first “setValue” is 0. It does not make the source code very clear, but anyway, it does work.
Thank you very much.

August 20, 2011

Lukas Geyer Lukas Geyer
Gene Splicer
2074 posts

You’re right. Although it is stated in the docs this behaviour isn’t very intuitive and should be fixed somewhen.

 
  ‹‹ using a db three times at the same time      Qt Licensing Help ››

You must log in to post a reply. Not a member yet? Register here!