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
@
#include <QtGui/QApplication>
#include <QProgressDialog>
#include <windows.h>int main(int argc, char *argv[])
{
QApplication a(argc, argv);QProgressDialog aProgress; aProgress.setAutoClose(false); aProgress.show(); // Loop 1 aProgress.setRange(0,65538); aProgress.setValue(0); Sleep(1000); aProgress.setValue(30000); Sleep(1000); aProgress.setValue(65538); Sleep(1000); // Loop 2 aProgress.setRange(78640,1862200); aProgress.setValue(78640); // ===> Crash !! SIGFPE // aProgress.setValue(78641); // This one would not crash !! Sleep(1000); aProgress.setValue(1200000); Sleep(1000); aProgress.setValue(1862200); Sleep(1000); return 0;
}
@ -
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.
-
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
bq. "QProgressDialog":http://doc.qt.nokia.com/latest/qprogressdialog.html#value-prop 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.
@
void QProgressDialog::setValue(int progress)
{
// ...
if (progress == 0) {
d->starttime.start();
d->forceTimer->start(d->showTime);
return;
} else {
bool need_show;
int elapsed = d->starttime.elapsed();
if (elapsed >= d->showTime) {
need_show = true;
} else {
if (elapsed > minWaitTime) {
int estimate;
int totalSteps = maximum() - minimum();
int myprogress = progress - minimum(); // 78640 - 78640 = 0
if ((totalSteps - myprogress) >= INT_MAX / elapsed)
estimate = (totalSteps - myprogress) / myprogress * elapsed; // division by zero
else
estimate = elapsed * (totalSteps - myprogress) / myprogress;
need_show = estimate >= d->showTime;
} else {
need_show = false;
}
}
// ...
@ -
[quote author="sierdzio" date="1313854964"]... I would imagine it has something to do with floats "floating" conversion around 78640, which may occasionally give different result than setRange ...[/quote]
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.
-
[quote author="Lukas Geyer" date="1313855989"][quote author="sierdzio" date="1313854964"]... I would imagine it has something to do with floats "floating" conversion around 78640, which may occasionally give different result than setRange ...[/quote]
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.[/quote]
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.
-
[quote author="sierdzio" date="1313854964"]Why windows.h? Try more Qt :P[/quote]
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).[quote author="Lukas Geyer" date="1313855813"]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
bq. "QProgressDialog":http://doc.qt.nokia.com/latest/qprogressdialog.html#value-prop 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.
[/quote]
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. -
You're right. Although it is stated in the docs this behaviour isn't very intuitive and should be fixed somewhen.