PDA

View Full Version : sendPostedEvents crash



stinos
27th October 2006, 20:07
Hi all!

For a previous job I wrote a win32 app using Qt3.2.1 (the commercial version without source included) & Qwt5.0, it basically does heavy real-time audio processing and displays it's results on several QwtPlots (10 in total, of which at max 5 are visible at the same time). Screen updates take place every 5 seconds or so.
Now I met the guy who's using the software yesterday, and he said that sometimes (like 1 out of 30 runs) he's getting a crash. He was able to trace it down to a call to QApplication::sendPostedEvents() in QwtPlot::replot().
I spent some time with him trying to figure out what goes wrong, and it seems to come down to this: after finding out at which offset in the qt dll the problem resides, it looks like there is some function (don't know which one, the name is not exported) calling QThreadStorage::hasLocalData(), which returns true. This results in that function trying to read memory filled with 0xfeeefee, which means it's freed, hence the crash.
Does this ring a bell for somebody?
Could the cause by that sendPostedEvents() is actually called from another thread then the main QApplication thread?

Any ideas are will be greatly appreciated!

Regards,
Stijn

wysota
27th October 2006, 22:13
Do you use threads in your application? If so, how exactly do you communicate between threads? Do you, by any chance, call any methods from widget classes from within worker threads?

stinos
28th October 2006, 10:38
There are 5 threads in total. They don't derive from QThread but from my own interface, but that's no point as it does the same basically.
Communication between them goes through thread-safe mechanisms only; eg when thread A wants to tell something to thread B, it invokes a method storing A's message in B's queue, so that B can dequeue it later. The method uses mutexes for synchronisation.
Flow goes like this:
audio thread processes signal (32 samples), stores it in a buffer queue; when the buffer is full (1024 samples) it tells thread A about this.

A does further processing on the buffer, then plots it on a QWidget (so this gets called from a "worker" thread! but it _never_ gives any crashes), and fills another buffer queue. Again, when the buffer is full (16384 samples), thread C is notified of this.

Thread C does some more processing on the buffer, and plots all 16384 samples (again, this is from a worker thread, but it never crashes). The processing from C gives 8 samples with the end result, which are plotted in a loop on 8 seperate small plots. (which only contain 32 samples maximum)
Here it crahes sometimes. I don't see much difference with the other plots, except that
one plot is updated right after the other.

wysota
28th October 2006, 13:13
The plotting can only take place from within the thread which owns the QApplication event queue (often called the "GUI thread"). QWidgets are not thread-safe. In your situation I would advise to use custom events from the worker threads to pass information to the GUI thread and let it do the plotting.

stinos
29th October 2006, 08:52
thanks for clarifying this! I wasn't entirely sure whether it's ok to access QWidget methods from different threads..

wysota
29th October 2006, 09:43
It's stated clearly in the docs: http://doc.trolltech.com/3.3/threads.html#6