Qt: Seltsamer Fehler



  • Hallo. Also zur Situation: Ich habe einen Thread, der Daten in aktualisiert, während der Haupt-Thread, in dem die Qt-GUI läuft, die Daten visualisiert. Mittels eines Scrollbalkens kann man sich durch die Daten durchscrollen. In regelmäßigen Zeitabständen wird der Bereich des Scrollbalkens erweitert (da neue Daten reinkommen) und die Daten neu gezeichnet, abhängig von der Position des Scrollbalkens. Ich habe natürlich brav Mutexes verwendet. Jedenfalls bekomme ich nach einer gewissen Laufzeit, meist mehrere Sekunden, folgenden Fehler:

    ASSERT: "!isEmpty(r)" in file painting/qregion_unix.cpp, line 117
    Aborted (core dumped)
    

    Der Debugger hat mir leider nicht groß helfen können. Es schaut so aus, als würde der Fehler immer an einer Stelle auftreten, wo ein Byte vom Daten-Eingabestream gelesen wird - Also im Daten-Thread. Allerdings geht für mich aus der Fehlermeldung hervor, dass es irgend etwas mit Qt zu tun hat ("qregion"). Also habe ich mal auf gut Glück ein paar Sektionen des GUI-Codes auskommentiert, und bin so zu der Erkenntnis gelangt, dass der Fehler nur dann eintritt, wenn ich darauf verzichte, bei jeder Bereichserweiterung des Scrollbalkens den Wert des Scrollbalkens sofort auf das Maximum zu setzen.

    Weiß jemand Rat, wie ich dem Fehler auf die Schliche kommen könnte?
    Vielen Dank im Voraus!



  • Nur geraten: Kann es sein, dass du aus deinem Datenthread heraus GUI-Elemente bearbeitest, QT das aber nur für den Hauptthread erlaubt.

    Vielleicht musst du etwas Quelltext zeigen.



  • Hm, in der Tat, das mache ich an einigen *anderen* Stellen. Ich werde mal versuchen dies durch Signals/Slots zu vermeiden. Vielleicht löst sich das Problem damit ja wirklich.



  • Aus der QT doku:

    Note that QCoreApplication::exec() must always be called from the main thread (the thread that executes main()), not from a QThread. In GUI applications, the main thread is also called the GUI thread because it's the only thread that is allowed to perform GUI-related operations.

    http://doc.trolltech.com/4.3/threads.html

    🙂



  • Erstmal danke für die Antwort. Dann eine Frage: Zählt so etwas wie "update ()" auch als "GUI-related operation"? Weiterhin: Gibt es vieleicht eine Möglichkeit, um schnell festzustellen, dass keine "GUI-related operations" von einem anderen Thread als dem GUI-Thread aus ausgeführt werden? Ich bin nämlich der Meinung, alle solchen Operationen durch den GUI-Thread erledigen zu lassen. Abstürzen tut meine GUI aber leider immernoch, obwohl mit einer anderen Fehlermeldung: einem gewöhnlichen Segmentation Fault. Könnte es vielleicht daran liegen, dass ich statt QThreads Posix-Threads benutze?



  • the[V]oid schrieb:

    Erstmal danke für die Antwort. Dann eine Frage: Zählt so etwas wie "update ()" auch als "GUI-related operation"?

    Ich würde sagen ja. Definitiv kann dir das aber wahrscheinlich nur Trolltech sagen.

    the[V]oid schrieb:

    Weiterhin: Gibt es vieleicht eine Möglichkeit, um schnell festzustellen, dass keine "GUI-related operations" von einem anderen Thread als dem GUI-Thread aus ausgeführt werden? Ich bin nämlich der Meinung, alle solchen Operationen durch den GUI-Thread erledigen zu lassen. Abstürzen tut meine GUI aber leider immernoch, obwohl mit einer anderen Fehlermeldung: einem gewöhnlichen Segmentation Fault.

    Mir ist keine Möglichkeit bekannt. Wenn dein Programm abstürzt nimm einen Debugger und schau mal nach, ob dein Programm die Segmentation-Fault innerhalb innerhalb von QT auslöst, wenn ja, dann machst du wahrscheinlich immer noch Probleme mit Threads.

    the[V]oid schrieb:

    Könnte es vielleicht daran liegen, dass ich statt QThreads Posix-Threads benutze?

    Eigentlich sollte QT innerhalb auch PThreads benutzten. Das sollte also kein Problem sein. Bin mir aber nicht sicher.



  • the[V]oid schrieb:

    Weiterhin: Gibt es vieleicht eine Möglichkeit, um schnell festzustellen, dass keine "GUI-related operations" von einem anderen Thread als dem GUI-Thread aus ausgeführt werden? Ich bin nämlich der Meinung, alle solchen Operationen durch den GUI-Thread erledigen zu lassen. Abstürzen tut meine GUI aber leider immernoch, obwohl mit einer anderen Fehlermeldung: einem gewöhnlichen Segmentation Fault.

    Mir ist keine Möglichkeit bekannt. Wenn dein Programm abstürzt nimm einen Debugger und schau mal nach, ob dein Programm die Segmentation-Fault innerhalb innerhalb von QT auslöst, wenn ja, dann machst du wahrscheinlich immer noch Probleme mit Threads.

    Das Segmentation Fault wird laut Debugger in folgender Methode ausgelöst:

    unsigned int View::volt_to_pixel ( const float& fVoltage ) {
    	return static_cast<unsigned int>( m_nHalfSurfaceHeight - fVoltage / m_fVperPixel );
    }
    

    Diese wird von paintEvent aus aufgerufen:

    void View::paintEvent ( QPaintEvent* pEvent ) {
    	// [...]
    	const Record& record0 = get_data () -> get_record ( nID - 1 );
    	const Record& record1 = get_data () -> get_record ( nID );
    	painter.drawLine (
    		ms_to_pixel ( record0.nTime ),
    		volt_to_pixel ( record0.fVoltage ),
    		ms_to_pixel ( record1.nTime ),
    		volt_to_pixel ( record1.fVoltage )
    	);
    	// [...]
    }
    

    Also vermute ich mal, dass es mit den Threads zusammenhängt. Ich werd wohl den ganzen Code nochmal durchgehen müssen.



  • Zählt so etwas wie "update ()" auch als "GUI-related operation"?

    definitiv ja.
    signal/slot hilft da auch nichts, weil die angeschlossene methode im gleichen thread-kontext ausgefuehrt wird.
    loesung: dem gui-thread ein event schicken; das wird erst bearbeitet wenn das naechste mal die eventloop laeuft.


Anmelden zum Antworten