2016-09-24 8 views
1

debuggen der app Ich arbeite über Ich habe einige seltsame Race-Bedingungen gefunden, die anscheinend nicht durch unseren Code verursacht werden. Einen Test mit folgendem Code machen Helgrind meldet in wenigen Sekunden mehr als 5000 mögliche Rennbedingungen.QThread: Race Condition mit dem einfachsten Code

Hier den Code:

#include <QApplication> 
#include <QThread> 

int main(int argc, char *argv[]) { 
    QApplication app(argc, argv); 

    QThread thread; 
    thread.start(); 

    return app.exec(); 
} 

Hier auf den Anfang des hellgrind Bericht:

==9856== Helgrind, a thread error detector 
==9856== Copyright (C) 2007-2015, and GNU GPL'd, by OpenWorks LLP et al. 
==9856== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info 
==9856== Command: /home/gianks/NetBeansProjects/ThreadTest/dist/Debug/GNU-Linux/ThreadTest 
==9856== 
==9856== ---Thread-Announcement------------------------------------------ 
==9856== 
==9856== Thread #1 is the program's root thread 
==9856== 
==9856== ---Thread-Announcement------------------------------------------ 
==9856== 
==9856== Thread #2 was created 
==9856== at 0x6041B1E: clone (clone.S:74) 
==9856== by 0x6852189: create_thread (createthread.c:102) 
==9856== by 0x6853EC3: [email protected]@GLIBC_2.2.5 (pthread_create.c:679) 
==9856== by 0x4C34BB7: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so) 
==9856== by 0x5571DB7: QThread::start(QThread::Priority) (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.5.1) 
==9856== by 0x40F9778: ??? (in /usr/lib/x86_64-linux-gnu/libQt5XcbQpa.so.5.5.1) 
==9856== by 0x40FF5E3: QXcbConnection::QXcbConnection(QXcbNativeInterface*, bool, unsigned int, char const*) (in /usr/lib/x86_64-linux-gnu/libQt5XcbQpa.so.5.5.1) 
==9856== by 0x41029EC: QXcbIntegration::QXcbIntegration(QStringList const&, int&, char**) (in /usr/lib/x86_64-linux-gnu/libQt5XcbQpa.so.5.5.1) 
==9856== by 0x40293AC: ??? (in /usr/lib/x86_64-linux-gnu/qt5/plugins/platforms/libqxcb.so) 
==9856== by 0x63E3DD1: QPlatformIntegrationFactory::create(QString const&, QStringList const&, int&, char**, QString const&) (in /usr/lib/x86_64-linux-gnu/libQt5Gui.so.5.5.1) 
==9856== by 0x63F0003: QGuiApplicationPrivate::createPlatformIntegration() (in /usr/lib/x86_64-linux-gnu/libQt5Gui.so.5.5.1) 
==9856== by 0x63F0F0C: QGuiApplicationPrivate::createEventDispatcher() (in /usr/lib/x86_64-linux-gnu/libQt5Gui.so.5.5.1) 
==9856== 
==9856== ---------------------------------------------------------------- 
==9856== 
==9856== Possible data race during read of size 4 at 0x599E9B0 by thread #1 
==9856== Locks held: none 
==9856== at 0x556AD30: QBasicMutex::unlockInternal() (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.5.1) 
==9856== by 0x4C344E7: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so) 
==9856== by 0x5571D23: QThread::start(QThread::Priority) (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.5.1) 
==9856== by 0x40F9778: ??? (in /usr/lib/x86_64-linux-gnu/libQt5XcbQpa.so.5.5.1) 
==9856== by 0x40FF5E3: QXcbConnection::QXcbConnection(QXcbNativeInterface*, bool, unsigned int, char const*) (in /usr/lib/x86_64-linux-gnu/libQt5XcbQpa.so.5.5.1) 
==9856== by 0x41029EC: QXcbIntegration::QXcbIntegration(QStringList const&, int&, char**) (in /usr/lib/x86_64-linux-gnu/libQt5XcbQpa.so.5.5.1) 
==9856== by 0x40293AC: ??? (in /usr/lib/x86_64-linux-gnu/qt5/plugins/platforms/libqxcb.so) 
==9856== by 0x63E3DD1: QPlatformIntegrationFactory::create(QString const&, QStringList const&, int&, char**, QString const&) (in /usr/lib/x86_64-linux-gnu/libQt5Gui.so.5.5.1) 
==9856== by 0x63F0003: QGuiApplicationPrivate::createPlatformIntegration() (in /usr/lib/x86_64-linux-gnu/libQt5Gui.so.5.5.1) 
==9856== by 0x63F0F0C: QGuiApplicationPrivate::createEventDispatcher() (in /usr/lib/x86_64-linux-gnu/libQt5Gui.so.5.5.1) 
==9856== by 0x5757A85: QCoreApplication::init() (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.5.1) 
==9856== by 0x5757AF5: QCoreApplication::QCoreApplication(QCoreApplicationPrivate&) (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.5.1) 
==9856== 
==9856== This conflicts with a previous write of size 4 by thread #2 
==9856== Locks held: none 
==9856== at 0x556A977: QBasicMutex::lockInternal() (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.5.1) 
==9856== by 0x4C34377: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so) 
==9856== by 0x5572754: ??? (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.5.1) 
==9856== by 0x4C34DB6: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so) 
==9856== by 0x68536F9: start_thread (pthread_create.c:333) 
==9856== by 0x6041B5C: clone (clone.S:109) 
==9856== Address 0x599e9b0 is in the Data segment of /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.5.1 
==9856== 
==9856== ---------------------------------------------------------------- 
==9856== 
==9856== Possible data race during write of size 8 at 0xBF41830 by thread #1 
==9856== Locks held: none 
==9856== at 0x556AD3A: QBasicMutex::unlockInternal() (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.5.1) 
==9856== by 0x4C344E7: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so) 
==9856== by 0x5571D23: QThread::start(QThread::Priority) (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.5.1) 
==9856== by 0x40F9778: ??? (in /usr/lib/x86_64-linux-gnu/libQt5XcbQpa.so.5.5.1) 
==9856== by 0x40FF5E3: QXcbConnection::QXcbConnection(QXcbNativeInterface*, bool, unsigned int, char const*) (in /usr/lib/x86_64-linux-gnu/libQt5XcbQpa.so.5.5.1) 
==9856== by 0x41029EC: QXcbIntegration::QXcbIntegration(QStringList const&, int&, char**) (in /usr/lib/x86_64-linux-gnu/libQt5XcbQpa.so.5.5.1) 
==9856== by 0x40293AC: ??? (in /usr/lib/x86_64-linux-gnu/qt5/plugins/platforms/libqxcb.so) 
==9856== by 0x63E3DD1: QPlatformIntegrationFactory::create(QString const&, QStringList const&, int&, char**, QString const&) (in /usr/lib/x86_64-linux-gnu/libQt5Gui.so.5.5.1) 
==9856== by 0x63F0003: QGuiApplicationPrivate::createPlatformIntegration() (in /usr/lib/x86_64-linux-gnu/libQt5Gui.so.5.5.1) 
==9856== by 0x63F0F0C: QGuiApplicationPrivate::createEventDispatcher() (in /usr/lib/x86_64-linux-gnu/libQt5Gui.so.5.5.1) 
==9856== by 0x5757A85: QCoreApplication::init() (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.5.1) 
==9856== by 0x5757AF5: QCoreApplication::QCoreApplication(QCoreApplicationPrivate&) (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.5.1) 
==9856== 
==9856== This conflicts with a previous read of size 8 by thread #2 
==9856== Locks held: none 
==9856== at 0x556A9A5: QMutex::lock() (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.5.1) 
==9856== by 0x4C34377: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so) 
==9856== by 0x5572754: ??? (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.5.1) 
==9856== by 0x4C34DB6: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so) 
==9856== by 0x68536F9: start_thread (pthread_create.c:333) 
==9856== by 0x6041B5C: clone (clone.S:109) 
==9856== Address 0xbf41830 is 112 bytes inside a block of size 168 alloc'd 
==9856== at 0x4C2F50F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so) 
==9856== by 0x556D793: QThread::QThread(QObject*) (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.5.1) 
==9856== by 0x40F96B2: ??? (in /usr/lib/x86_64-linux-gnu/libQt5XcbQpa.so.5.5.1) 
==9856== by 0x40FF5D4: QXcbConnection::QXcbConnection(QXcbNativeInterface*, bool, unsigned int, char const*) (in /usr/lib/x86_64-linux-gnu/libQt5XcbQpa.so.5.5.1) 
==9856== by 0x41029EC: QXcbIntegration::QXcbIntegration(QStringList const&, int&, char**) (in /usr/lib/x86_64-linux-gnu/libQt5XcbQpa.so.5.5.1) 
==9856== by 0x40293AC: ??? (in /usr/lib/x86_64-linux-gnu/qt5/plugins/platforms/libqxcb.so) 
==9856== by 0x63E3DD1: QPlatformIntegrationFactory::create(QString const&, QStringList const&, int&, char**, QString const&) (in /usr/lib/x86_64-linux-gnu/libQt5Gui.so.5.5.1) 
==9856== by 0x63F0003: QGuiApplicationPrivate::createPlatformIntegration() (in /usr/lib/x86_64-linux-gnu/libQt5Gui.so.5.5.1) 
==9856== by 0x63F0F0C: QGuiApplicationPrivate::createEventDispatcher() (in /usr/lib/x86_64-linux-gnu/libQt5Gui.so.5.5.1) 
==9856== by 0x5757A85: QCoreApplication::init() (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.5.1) 
==9856== by 0x5757AF5: QCoreApplication::QCoreApplication(QCoreApplicationPrivate&) (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.5.1) 
==9856== by 0x63F2D08: QGuiApplication::QGuiApplication(QGuiApplicationPrivate&) (in /usr/lib/x86_64-linux-gnu/libQt5Gui.so.5.5.1) 
==9856== Block was alloc'd by thread #1 
==9856== 
==9856== ---------------------------------------------------------------- 
==9856== 
==9856== Possible data race during read of size 8 at 0xBF41830 by thread #2 
==9856== Locks held: none 
==9856== at 0x556A92D: QBasicMutex::lockInternal() (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.5.1) 
==9856== by 0x4C34377: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so) 
==9856== by 0x5572754: ??? (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.5.1) 
==9856== by 0x4C34DB6: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so) 
==9856== by 0x68536F9: start_thread (pthread_create.c:333) 
==9856== by 0x6041B5C: clone (clone.S:109) 
==9856== 
==9856== This conflicts with a previous write of size 8 by thread #1 
==9856== Locks held: none 
==9856== at 0x556AD3A: QBasicMutex::unlockInternal() (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.5.1) 
==9856== by 0x4C344E7: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so) 
==9856== by 0x5571D23: QThread::start(QThread::Priority) (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.5.1) 
==9856== by 0x40F9778: ??? (in /usr/lib/x86_64-linux-gnu/libQt5XcbQpa.so.5.5.1) 
==9856== by 0x40FF5E3: QXcbConnection::QXcbConnection(QXcbNativeInterface*, bool, unsigned int, char const*) (in /usr/lib/x86_64-linux-gnu/libQt5XcbQpa.so.5.5.1) 
==9856== by 0x41029EC: QXcbIntegration::QXcbIntegration(QStringList const&, int&, char**) (in /usr/lib/x86_64-linux-gnu/libQt5XcbQpa.so.5.5.1) 
==9856== by 0x40293AC: ??? (in /usr/lib/x86_64-linux-gnu/qt5/plugins/platforms/libqxcb.so) 
==9856== by 0x63E3DD1: QPlatformIntegrationFactory::create(QString const&, QStringList const&, int&, char**, QString const&) (in /usr/lib/x86_64-linux-gnu/libQt5Gui.so.5.5.1) 
==9856== Address 0xbf41830 is 112 bytes inside a block of size 168 alloc'd 
==9856== at 0x4C2F50F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so) 
==9856== by 0x556D793: QThread::QThread(QObject*) (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.5.1) 
==9856== by 0x40F96B2: ??? (in /usr/lib/x86_64-linux-gnu/libQt5XcbQpa.so.5.5.1) 
==9856== by 0x40FF5D4: QXcbConnection::QXcbConnection(QXcbNativeInterface*, bool, unsigned int, char const*) (in /usr/lib/x86_64-linux-gnu/libQt5XcbQpa.so.5.5.1) 
==9856== by 0x41029EC: QXcbIntegration::QXcbIntegration(QStringList const&, int&, char**) (in /usr/lib/x86_64-linux-gnu/libQt5XcbQpa.so.5.5.1) 
==9856== by 0x40293AC: ??? (in /usr/lib/x86_64-linux-gnu/qt5/plugins/platforms/libqxcb.so) 
==9856== by 0x63E3DD1: QPlatformIntegrationFactory::create(QString const&, QStringList const&, int&, char**, QString const&) (in /usr/lib/x86_64-linux-gnu/libQt5Gui.so.5.5.1) 
==9856== by 0x63F0003: QGuiApplicationPrivate::createPlatformIntegration() (in /usr/lib/x86_64-linux-gnu/libQt5Gui.so.5.5.1) 
==9856== by 0x63F0F0C: QGuiApplicationPrivate::createEventDispatcher() (in /usr/lib/x86_64-linux-gnu/libQt5Gui.so.5.5.1) 
==9856== by 0x5757A85: QCoreApplication::init() (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.5.1) 
==9856== by 0x5757AF5: QCoreApplication::QCoreApplication(QCoreApplicationPrivate&) (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.5.1) 
==9856== by 0x63F2D08: QGuiApplication::QGuiApplication(QGuiApplicationPrivate&) (in /usr/lib/x86_64-linux-gnu/libQt5Gui.so.5.5.1) 
==9856== Block was alloc'd by thread #1 

Gibt es tatsächlich ein Fehler?

Ein Hinweis: Ich habe auch versucht, starten mit einer Warteschlange Verbindung, den gleichen Effekt, so dass die Ereignisschleife vor dem anderen Thread ist keine Lösung.

Dank

Antwort

0

Sie verwenden QThread nicht in der richtigen Art und Weise, wie pro Qt docs http://doc.qt.io/qt-5/qthread.html

Sie müssen entweder QThread Unterklasse und run() neu implementieren, oder Sie können durch Arbeiter Objekte, um sie zu bewegen der Thread mit QObject :: moveToThread().

+0

Es ist vollkommen legitim, nur zu starten() eine einfache QThread Instanz . – peppe

+0

@peppe irgendeine bitte? – HazemGomaa

+0

Die QThread-Dokumentation für [start] (https://doc.qt.io/qt-5/qthread.html#start) sagt: * Beginnt die Ausführung des Threads durch Aufruf von run() *. Die Dokumentation für [run] (https://doc.qt.io/qt-5/qthread.html#run) sagt: * [...] Die Standardimplementierung ruft einfach exec() * auf. Mit anderen Worten, es ist absolut legitim und das Verhalten ist gut definiert. – peppe

4

helgrind versteht die in Qt selbst verwendeten Atome nicht. Sie müssen diese Warnung unterdrücken (und sie ignorieren). Fetch dies:

https://github.com/KDE/kde-dev-scripts/blob/master/kde.supp

Und fügen --suppressions=/path/to/kde.supp zum Helgrind Kommandozeile.

Weitere Informationen zur Verwendung von Helgrind in einer Qt-Anwendung finden Sie unter this blog post.


(Randbemerkung: a. QThread zu zerstören, die nach wie vor wird laufen das Programm zum Absturz bringen, so sicher sein, sie zu verbinden, bevor aus dem Haupt Rückkehr)

+0

Danke für die Antwort, ich habe schon gefunden und versucht, ohne Glück, was Sie vorgeschlagen haben. Ich werde es noch einmal versuchen, die möglichen Ergebnisse in wenigen Stunden zu veröffentlichen, danke! – Gianks

+0

Verwenden Sie einen Debug-Build von Qt? (Denken, dass ein Release-Build die Atomics inline und damit Helgrind verwirren könnte) – peppe