PDA

View Full Version : crash in emit()



mhoover
25th August 2009, 02:56
For some reason when I try to emit a QString I get a segfault.


void UDPClient::logEvent( const QString & event, int at_debug ) {
QString event2 = event;
stopper.lock();
emit debugEvent( event2 ); // <--- Segfaults right here
stopper.unlock();
}

When I went digging through the backtrace I found it was trying to call all the connected slots using a Qt::AutoConnection.


if ((c->connectionType == Qt::AutoConnection

(According to the qtcreator debugger, c->connectionType was 0 which is the same as Qt::AutoConnection).

The strange part is the only connection I make to this signal I emit is to another signal in the QThread that owns this object. And it never reaches any slots.

Anyway, I can just comment it out for now, but I'd like to know what mistake I'm making.

wysota
25th August 2009, 08:01
What's the point of using the mutex here?

mhoover
25th August 2009, 19:54
The mutex doesn't seem to make any difference, but since I have so many of these running in so many threads I thought it might be worth a try.

wysota
25th August 2009, 21:48
Can you show us the complete backtrace from the debugger?

mhoover
25th August 2009, 23:34
Here's the backtrace stack:

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0xb5eaab90 (LWP 30333)]
0x00a5d258 in QMetaObject::activate (sender=0x828dfd0, from_signal_index=6, to_signal_index=6, argv=0xb5ea9580) at kernel/qobject.cpp:3080
3080 if ((c->connectionType == Qt::AutoConnection
(gdb) bt
#0 0x00a5d258 in QMetaObject::activate (sender=0x828dfd0, from_signal_index=6, to_signal_index=6, argv=0xb5ea9580) at kernel/qobject.cpp:3080
#1 0x00a5d967 in QMetaObject::activate (sender=0x828dfd0, m=0x80b036c, local_signal_index=2, argv=0xb5ea9580) at kernel/qobject.cpp:3185
#2 0x080a1c78 in UDPClient::debugEvent (this=0x828dfd0, _t1=@0xb5ea95b0) at moc_udpclient.cpp:187
#3 0x0809c99e in UDPClient::logEvent (this=0x828dfd0, event=@0xb5ea9a10, at_debug=3) at udpclient.cpp:138
#4 0x0809d365 in UDPClient::sendRequest (this=0x828dfd0) at udpclient.cpp:238
#5 0x080a21e6 in UDPClient::qt_metacall (this=0x828dfd0, _c=QMetaObject::InvokeMetaMethod, _id=5, _a=0xb5ea9b08) at moc_udpclient.cpp:151
#6 0x00a5d3c8 in QMetaObject::activate (sender=0xb3d00f50, from_signal_index=4, to_signal_index=4, argv=0x0) at kernel/qobject.cpp:3111
#7 0x00a5d967 in QMetaObject::activate (sender=0xb3d00f50, m=0xb59aa4, local_signal_index=0, argv=0x0) at kernel/qobject.cpp:3185
#8 0x00a679a1 in QSingleShotTimer::timeout (this=0xb3d00f50) at .moc/debug-shared/qtimer.moc:76
#9 0x00a67ade in QSingleShotTimer::timerEvent (this=0xb3d00f50) at kernel/qtimer.cpp:298
#10 0x00a5c43a in QObject::event (this=0xb3d00f50, e=0xb5eaa114) at kernel/qobject.cpp:1073
#11 0x00d51ea9 in QApplicationPrivate::notify_helper (this=0x8173480, receiver=0xb3d00f50, e=0xb5eaa114) at kernel/qapplication.cpp:4057
#12 0x00d52261 in QApplication::notify (this=0xbf957038, receiver=0xb3d00f50, e=0xb5eaa114) at kernel/qapplication.cpp:3604
#13 0x00a44a7c in QCoreApplication::notifyInternal (this=0xbf957038, receiver=0xb3d00f50, event=0xb5eaa114) at kernel/qcoreapplication.cpp:610
#14 0x00d4e381 in QCoreApplication::sendEvent (receiver=0xb3d00f50, event=0xb5eaa114) at ../../include/QtCore/qcoreapplication.h:213
#15 0x00a7e1f5 in QTimerInfoList::activateTimers (this=0x8288f34) at kernel/qeventdispatcher_unix.cpp:572
#16 0x00a7b094 in timerSourceDispatch (source=0x8288f00) at kernel/qeventdispatcher_glib.cpp:164
#17 0x00325372 in g_main_context_dispatch () from /lib/libglib-2.0.so.0
#18 0x00328366 in ?? () from /lib/libglib-2.0.so.0
#19 0x003288be in g_main_context_iteration () from /lib/libglib-2.0.so.0
#20 0x00a7aa84 in QEventDispatcherGlib::processEvents (this=0x8288dd8, flags={i = -1242914168}) at kernel/qeventdispatcher_glib.cpp:324
#21 0x00a40ef6 in QEventLoop::processEvents (this=0xb5eaa31c, flags={i = -1242914100}) at kernel/qeventloop.cpp:149
#22 0x00a41152 in QEventLoop::exec (this=0xb5eaa31c, flags={i = -1242914012}) at kernel/qeventloop.cpp:200
#23 0x009305e5 in QThread::exec (this=0xbf956ea4) at thread/qthread.cpp:487
#24 0x0809fd04 in UDPClientThread::run (this=0xbf956ea4) at udpclient.cpp:488
#25 0x00934d39 in QThreadPrivate::start (arg=0xbf956ea4) at thread/qthread_unix.cpp:189
#26 0x0014e49b in start_thread () from /lib/libpthread.so.0
#27 0x0342842e in clone () from /lib/libc.so.6

spirit
26th August 2009, 06:49
as I see you use threads, but I also noticed that somewhere QCoreApplication::sendEvent is used, it is wrong. communication between threads must be made whith the help of QCoreApplication::postEvent or using Qt::QueuedConnection.

wysota
26th August 2009, 08:11
as I see you use threads, but I also noticed that somewhere QCoreApplication::sendEvent is used, it is wrong. communication between threads must be made whith the help of QCoreApplication::postEvent or using Qt::QueuedConnection.

This is an internal Qt call so it has to be correct. The problem is elsewhere but I would guess the backtrace is useless - I'd say the problem is really in some other thread and it only manifests itself in this thread by crashing. That's just a guess though...

mhoover
26th August 2009, 20:17
Thanks wysota, spirit.

Wysota was right about the backtrace being worthless. It turns out the problem was I had an array allocated to the right size and then the customer asked for more elements and I forgot to increase the size of the array. None of this was in the back trace. It kind of bothers me that there is no tool I can use to find that ... (I would have guessed that valgrind would catch it, but it didn't). And it bothers me to make mistakes like this ...

Spirit: you may have been right. I turned off some of the queued connections when the emit caused a crash just to see what would happen. I should put it back now that I know what the problem is.

Good sleuthing.

wysota
26th August 2009, 23:19
(I would have guessed that valgrind would catch it, but it didn't).
Valgrind cares about allocated memory, not about non-allocated memory. Although it should warn you about reading/writing past the allocated block.

Kumosan
27th August 2009, 07:36
Apart from the crash, your usage of stopper.lock/stopper.unlock is bad style. Not exception safe. Even if the code between lock and unlock cannot throw an exception now, you never know how this might change in the future. You might want to read about RAII.