How can I prevent the QT event stack from overflowing?

advertisements

I am making a QT application that updates the window based on the information it receives from sockets. This is how I went about doing this:

  1. set up a timer that causes application to check sockets

  2. after new information is recieved (if any), I change context data that is used in painting the widget and call redraw on it

  3. naturally, my code that does the drawing i need is in paint event

However, I have run into a problem. The application isn't stable, and will randomly crash (usually after sending to socket started). Under debug, the stack trace shows it crashes in the depths of QT itself, on the allocation - I presume, judging by the stack - of the another paint event.

How can I prevent this from happening? Maybe, by not calling redraw if the paintng isn't actually done yet?

Code that handles recieving new data; dt.listen() returns number of changed items.

void CommandPanel::update()
{
    //printf("Some drawing is done!\n");
    static int udel = 0;
    udel += 1+dt.listen();
    if ( udel > 40)
    {
        this->repaint(); //!!!
        udel = 0;
    }
}

Code that binds it to timer

//object T that is derived from QWidget is created
QTimer timer;
QObject::connect(&timer, SIGNAL(timeout()), &T, SLOT(update()));
timer.start(1000 / 10);
T.show();

Under debug i reciever a segmentation fault signal when i arrive on the line with '!!!' in comment. Here is a full stack trace.

Thread 3 (Thread 0xb75b9b70 (LWP 9183)): _#0 0x0012e416 in __kernel_vsyscall () No symbol table info available.

_#1 0x00e49834 in [email protected]@GLIBC_2.3.2 () from /lib/i386-linux-gnu/libpthread.so.0 No symbol table info available.

_#2 0x01472f0e in ?? () from /usr/lib/i386-linux-gnu/libgthread-2.0.so.0 No symbol table info available.

_#3 0x0114042c in ?? () from /lib/i386-linux-gnu/libglib-2.0.so.0 No symbol table info available.

_#4 0x01140f6d in g_async_queue_timed_pop () from /lib/i386-linux-gnu/libglib-2.0.so.0 No symbol table info available.

_#5 0x01198980 in ?? () from /lib/i386-linux-gnu/libglib-2.0.so.0 No symbol table info available.

_#6 0x011962df in ?? () from /lib/i386-linux-gnu/libglib-2.0.so.0 No symbol table info available.

_#7 0x00e44e99 in start_thread () from /lib/i386-linux-gnu/libpthread.so.0 No symbol table info available.

_#8 0x0105573e in clone () from /lib/i386-linux-gnu/libc.so.6 No symbol table info available.

Thread 2 (Thread 0xb7dbab70 (LWP 9072)): _#0 0x0012e416 in __kernel_vsyscall () No symbol table info available.

_#1 0x01046f76 in poll () from /lib/i386-linux-gnu/libc.so.6 No symbol table info available.

_#2 0x0117d84b in g_poll () from /lib/i386-linux-gnu/libglib-2.0.so.0 No symbol table info available.

_#3 0x0116d1af in ?? () from /lib/i386-linux-gnu/libglib-2.0.so.0 No symbol table info available.

_#4 0x0116d92b in g_main_loop_run () from /lib/i386-linux-gnu/libglib-2.0.so.0 No symbol table info available.

_#5 0x0166b304 in ?? () from /usr/lib/i386-linux-gnu/libgio-2.0.so.0 No symbol table info available. _#6 0x011962df in ?? () from /lib/i386-linux-gnu/libglib-2.0.so.0 No symbol table info available.

_#7 0x00e44e99 in start_thread () from /lib/i386-linux-gnu/libpthread.so.0 No symbol table info available.

_#8 0x0105573e in clone () from /lib/i386-linux-gnu/libc.so.6 No symbol table info available.

Thread 1 (Thread 0xb7fe4710 (LWP 8938)): _#0 0x00d183f8 in QMetaObject::activate(QObject*, QMetaObject const*, int, void**) () from /usr/lib/libQtCore.so.4 No symbol table info available.

_#1 0x00d652f7 in QTimer::timeout() () from /usr/lib/libQtCore.so.4 No symbol table info available.

_#2 0x00d1e3ee in QTimer::timerEvent(QTimerEvent*) () from /usr/lib/libQtCore.so.4 No symbol table info available.

_#3 0x00d17214 in QObject::event(QEvent*) () from /usr/lib/libQtCore.so.4 No symbol table info available.

_#4 0x0025cd24 in QApplicationPrivate::notify_helper(QObject*, QEvent*) () from /usr/lib/libQtGui.so.4 No symbol table info available.

_#5 0x002618ce in QApplication::notify(QObject*, QEvent*) () from /usr/lib/libQtGui.so.4 No symbol table info available.

_#6 0x00d020bb in QCoreApplication::notifyInternal(QObject*, QEvent*) () from /usr/lib/libQtCore.so.4 No symbol table info available.

_#7 0x00d321e4 in ?? () from /usr/lib/libQtCore.so.4 No symbol table info available.

_#8 0x00d2ee27 in ?? () from /usr/lib/libQtCore.so.4 No symbol table info available.

_#9 0x0116caa8 in g_main_context_dispatch () from /lib/i386-linux-gnu/libglib-2.0.so.0 No symbol table info available.

_#10 0x0116d270 in ?? () from /lib/i386-linux-gnu/libglib-2.0.so.0 No symbol table info available.

_#11 0x0116d524 in g_main_context_iteration () from /lib/i386-linux-gnu/libglib-2.0.so.0 No symbol table info available.

_#12 0x00d2f53c in QEventDispatcherGlib::processEvents(QFlags) () from /usr/lib/libQtCore.so.4 No symbol table info available.

_#13 0x00310775 in ?? () from /usr/lib/libQtGui.so.4 No symbol table info available.

_#14 0x00d01289 in QEventLoop::processEvents(QFlags) () from /usr/lib/libQtCore.so.4 No symbol table info available.

_#15 0x00d01522 in QEventLoop::exec(QFlags) () from /usr/lib/libQtCore.so.4 No symbol table info available.

_#16 0x00d05ecc in QCoreApplication::exec() () from /usr/lib/libQtCore.so.4 No symbol table info available.

_#17 0x0025a8e7 in QApplication::exec() () from /usr/lib/libQtGui.so.4 No symbol table info available.

_#18 0x0804ac19 in main (argc=1, argv=0xbffff8a4) at ../wargui/main.cpp:40

    app = <incomplete type>
    timer = <incomplete type>
    T = {<QLabel> = {<No data fields>}, view = 0x10e33c0, dt = {qflag = 0, channelSockets = {0x8566108 "/tmp/channel1", 0x8567788 "/tmp/channel2", 0x8565298 "/tmp/channel3", 0x8565330 "/tmp/channel4", 0x8567db8 "/tmp/channel5", 0x8567e00 "/tmp/channel6", 0x8567108 "/tmp/channel7"}, mesSources = {0x8567e78, 0x85653a0, 0x85652b0, 0x8565348, 0x8567dd0, 0x85670d8, 0x8567120}, cossock = 33, chansocks = {26, 27, 28, 29, 30, 31, 32}, logLength = {0, 0, 0, 0, 0, 0, 0, 1, 1}, logs = {0x8568620, 0x8568788, 0x85688f0, 0x8568a58, 0x8568bc0, 0x8568d28, 0x8568e90, 0x8568ff8, 0x8569160}, targets = 0x85651e0}}
    pm = <incomplete type>
    r = -1073743880

I must also add the following. If the qt application have started before the messages start arriving on socket, it works without falling. Otherwise, when the messages are already being sent and then the qt application starts, it falls once the first call on update() is made.


I faced this kind of problems the first time I had overridden an update() method.

Gnud is right calling directly the original update() should fix your problem, if you have something to do/draw/update/paint when a paint event occurs, re-implement paintEvent(QPaintEvent*).

In addition to that, in order to trigger your paint event you can connect a slot to the readyRead() QSocket signal. In this slot you can evaluate bytesAvailable() until a decent amount of data is reached. Then you call an update(). You should also create/reset a one shot timer just in case the data you just received was the last, and the 'decent' amount will never be reached!