IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Qt Discussion :

QDialog et ses dérivées provoquent des SEGFAULT


Sujet :

Qt

  1. #1
    Membre confirmé Avatar de TNT89
    Inscrit en
    Juillet 2007
    Messages
    358
    Détails du profil
    Informations personnelles :
    Âge : 34

    Informations forums :
    Inscription : Juillet 2007
    Messages : 358
    Points : 615
    Points
    615
    Par défaut QDialog et ses dérivées provoquent des SEGFAULT
    Bonjour à tous,

    J'ai un problème très ennuyeux avec Qt. J'avais l'habitude de passer par des appels statiques dans le syle des suivantes:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    QString filename = QFileDialog::getOpenFileName(NULL, tr("Load a file"), ".", "*.*");
    // ou
    QMessageBox::information(this, tr("Error!"), error.what());
    Malheureusement, avec ma nouvelle configuration, ces appels provoquent un SEGFAULT. Pour le QFileDialog, j'obtient avec GDB :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    #0 0x7ffff57bc12f	??() (/lib/x86_64-linux-gnu/libc.so.6:??)
    #1 0x7ffff4d1475c	XSetCommand() (/usr/lib/x86_64-linux-gnu/libX11.so.6:??)
    #2 0x7ffff4d194bb	XSetWMProperties() (/usr/lib/x86_64-linux-gnu/libX11.so.6:??)
    #3 0x7ffff70aeec5	QWidgetPrivate::create_sys(this=0x6d4f50, window=27263364, initializeWindow=true, destroyOldWindow=118) (kernel/qwidget_x11.cpp:799)
    #4 0x7ffff70605e2	QWidget::create(this=0x7c5210, window=0, initializeWindow=true, destroyOldWindow=true) (kernel/qwidget.cpp:1467)
    #5 0x7ffff706ae8a	QWidget::setVisible(this=0x7c5210, visible=<optimized out>) (kernel/qwidget.cpp:7596)
    #6 0x7ffff74c66ec	QDialog::setVisible(this=0x7c5210, visible=<optimized out>) (dialogs/qdialog.cpp:739)
    #7 0x7ffff74c5490	show(this=0x7c5210) (../../include/QtGui/../../src/gui/kernel/qwidget.h:487)
    #8 (	QDialog::exec(this=<optimized out>) (dialogs/qdialog.cpp:543)
    #9 0x408180	Interface::openFile() () (??:??)
    #10 0x4088ef	Interface::loadPipeline() () (??:??)
    #11 0x409b24	Interface::qt_metacall(QMetaObject::Call, int, void**) () (??:??)
    #12 0x7ffff6aebb1a	QMetaObject::activate(sender=0x685f40, m=<optimized out>, local_signal_index=<optimized out>, argv=0x0) (kernel/qobject.cpp:3278)
    #13 0x7ffff73c5f21	QAbstractButtonPrivate::emitReleased(this=<optimized out>) (widgets/qabstractbutton.cpp:574)
    #14 0x7ffff73c712c	QAbstractButtonPrivate::click(this=0x779c90) (widgets/qabstractbutton.cpp:537)
    #15 0x7ffff73c73ac	QAbstractButton::mouseReleaseEvent(this=0x685f40, e=0x7fffffffda20) (widgets/qabstractbutton.cpp:1121)
    #16 0x7ffff7067016	QWidget::event(this=0x685f40, event=0x7fffffffda20) (kernel/qwidget.cpp:8259)
    #17 0x7ffff70169f4	notify_helper(e=0x7fffffffda20, receiver=0x685f40, this=0x680c70) (kernel/qapplication.cpp:4467)
    #18 (	QApplicationPrivate::notify_helper(this=0x680c70, receiver=0x685f40, e=0x7fffffffda20) (kernel/qapplication.cpp:4439)
    #19 0x7ffff701c17b	QApplication::notify(this=<optimized out>, receiver=0x685f40, e=0x7fffffffda20) (kernel/qapplication.cpp:4028)
    #20 0x7ffff6ad8fbc	QCoreApplication::notifyInternal(this=0x680c40, receiver=0x685f40, event=0x7fffffffda20) (kernel/qcoreapplication.cpp:731)
    #21 0x7ffff70179c2	sendEvent(event=<optimized out>, receiver=<optimized out>) (../../include/QtCore/../../src/corelib/kernel/qcoreapplication.h:215)
    #22 (	QApplicationPrivate::sendMouseEvent(receiver=0x685f40, event=0x7fffffffda20, alienWidget=0x0, nativeWidget=0x685f40, buttonDown=0x0, lastMouseReceiver=..., spontaneous=true) (kernel/qapplication.cpp:3127)
    #23 0x7ffff7093de8	QETWidget::translateMouseEvent(this=0x685f40, event=<optimized out>) (kernel/qapplication_x11.cpp:4465)
    #24 0x7ffff7092bea	QApplication::x11ProcessEvent(this=0x680c40, event=0x7fffffffe140) (kernel/qapplication_x11.cpp:3591)
    #25 0x7ffff70bad32	x11EventSourceDispatch(s=0x685eb0, callback=0, user_data=0x0) (kernel/qguieventdispatcher_glib.cpp:146)
    #26 0x7ffff45d50cf	g_main_context_dispatch() (/lib/x86_64-linux-gnu/libglib-2.0.so.0:??)
    #27 0x7ffff45d58c8	??() (/lib/x86_64-linux-gnu/libglib-2.0.so.0:??)
    #28 0x7ffff45d5a99	g_main_context_iteration() (/lib/x86_64-linux-gnu/libglib-2.0.so.0:??)
    #29 0x7ffff6b03abf	QEventDispatcherGlib::processEvents(this=0x682210, flags=<optimized out>) (kernel/qeventdispatcher_glib.cpp:422)
    La structure de l'application est assez simple : une classe Application dérivant de QApplication et possedant un pointeur vers une classe Interface dérivant de QWidget. Les appels sont réalisés depuis des fonctions "public slots" et appelés par un évènement (QPushButton::released()).

    J'ai donc essayé sans les appels statiques avec le code suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    QPointer<QFileDialog> dlg = new QFileDialog(this);
    dlg->setFileMode(QFileDialog::ExistingFile);
    dlg->setOption(QFileDialog::DontUseNativeDialog, true); //J'ai essayé ce drapeau avec les appels statiques sans plus de succès
    dlg->selectNameFilter("*.ppl");
    dlg->exec(); //ou dlg->show();
    //exploitation...
    delete dlg;
    Et j'obtiens la même erreur... SAUF quand j'appelle cette fonction sans passer "par un évènement" mais en la lançant à la main directement à la fin du constructeur de Interface par exemple. En fait, tant que je n'ai pas appellé la fonction exec() de QApplication, tout va bien.

    Je pense donc, très fortement pour une mauvaise configuration de mon système :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    uname -a
    Linux *** 3.1.0-1-amd64 #1 Fri Dec 23 16:37:11 UTC x86_64 GNU/Linux
    g++ -v
    gcc version 4.6.2 (Debian 4.6.2-11)
    make -v
    GNU Make 3.81
    qmake -v
    QMake version 2.01a
    Using Qt version 4.7.3 in /usr/lib
    dbus-daemon --version
    D-Bus Message Bus Daemon 1.2.24
    Xorg -version
    X.Org X Server 1.11.2.902 (1.11.3 RC 2)
    Release Date: 2011-12-09
    Le truc c'est que je n'utilise pas Gnome mais seulement un compositeur : Compiz-GTK...

    Enfin, un code minimal pour reproduire l'erreur :
    Interface.hpp :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    #ifndef __TEST_INTERFACE__
    #define __TEST_INTERFACE__
     
    	#include <iostream>
    	#include <QApplication>
    	#include <QWidget>
    	#include <QPushButton>
    	#include <QVBoxLayout>
    	#include <QFileDialog>
    	#include <QMessageBox>
            #include <QPointer>
     
    	// Object
    		class Interface : public QWidget
    		{
    			Q_OBJECT
     
    			private :
    				QVBoxLayout* 	layout;
    				QPushButton	*chPpl;
     
    			public :
    				Interface(void);
     
    			public slots :
    				void loadFile(void);
    				void openFile(void);
    		};
     
    		class Application : public QApplication
    		{
    			Q_OBJECT
     
    			private :
    				Interface	*interface;
     
    			public :
    				Application(int argc, char** argv);
    		};
     
    #endif
    Interface.cpp :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    #include "interface.hpp"
    // Src :
    	Interface::Interface(void)
    	{
    		chPpl	= new QPushButton("Load a file", this);
    		layout 	= new QVBoxLayout(this);
    		layout->addWidget(chPpl);
    		QObject::connect(chPpl,		SIGNAL(released()), this, SLOT(openFile()));
    		setGeometry(1000, 100, 800, 700);
    		show();
                    // Si j'appelle ici, openFile() ou loadFile(), les deux fonctionnent!
    	}
     
    	void Interface::openFile(void)
    	{
                    // L'appel suivant provoque le SEGFAULT
    		QString filename = QFileDialog::getOpenFileName(NULL, tr("Load a file"), ".", "*.*", NULL, QFileDialog::DontUseNativeDialog);
     
    		if(!filename.isEmpty())
    		{
    			std::cout << "Loading : " << filename.toUtf8().constData() << std::endl;
    		}
    	}
     
    	void Interface::loadFile(void)
    	{
    		std::cout << "Loading GUI..." << std::endl;
    		openFile(); // Provoque le SEGFAULT
    		std::cout << "...end GUI" << std::endl;
     
                    // Loading file
    	}
     
    	Application::Application(int argc, char** argv)
    	 : QApplication(argc,argv)
    	{
    		interface = new Interface;
                    // Si j'appelle d'ici interface->loadFile() ou interface->openFile(), ils fonctionnent!
    	}
    main.cpp :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    #include "interface.hpp"
     
    int main(int argc, char** argv)
    {
    	std::cout << "Test interface..." << std::endl;
     
    	Application* a = new Application(argc, argv);
    	return a->exec();
    }
    interface.pro (avec ou sans debug) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    CONFIG 		+= 	qt debug
    INCLUDEPATH  	+= 	/usr/local/lib
    HEADERS      	+= 	interface.hpp
    SOURCES      	+= 	main.cpp \
    			interface.cpp
    Je suis preneur de toutes les idées!

    Vous remerciant,

  2. #2
    Membre confirmé Avatar de TNT89
    Inscrit en
    Juillet 2007
    Messages
    358
    Détails du profil
    Informations personnelles :
    Âge : 34

    Informations forums :
    Inscription : Juillet 2007
    Messages : 358
    Points : 615
    Points
    615
    Par défaut
    Etape 1 :
    Etape 2 :

    Quand on est bête il faut lire la doc... Et notamment http://developer.qt.nokia.com/doc/qt...l#QApplication qui stipule bien avec un beau Warning, qu'il faut que argv et argc soient valides pour la durée de vie de QApplication.

    Du coup la correction est simple, il faut passer argc par référence et pas par copie (sinon la copie est détruite après la fin du constructeur et la mémoire peut-être réutilisée... ce qui à mon avis engendre la lecture d'arguments fictifs dans argv, notamment des arguments interprêtés comme des instructions de taille pour le serveur X dans mon cas, je n'ai aucune idée de pourquoi j'arrive à faire fonctionner ce code avec Gnome d'installé, et le reproduire sur plusieurs systèmes).

    Dans interface.hpp et interface.cpp, on doit remplacer les lignes correspondante par :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Application(int& argc, char** argv)
    Et miracle... vous connaissez la suite!

    (merci)

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Linux] Ajout d'un JMP provoque une segfault
    Par Zenol dans le forum Assembleur
    Réponses: 9
    Dernier message: 06/04/2008, 12h24
  2. Image provoquant des erreurs
    Par fred1599 dans le forum Erreurs - Avertissements
    Réponses: 3
    Dernier message: 14/11/2007, 15h28
  3. "Jonas stop" provoque des erreurs
    Par crv dans le forum JOnAS
    Réponses: 1
    Dernier message: 27/10/2006, 15h26
  4. Réponses: 1
    Dernier message: 09/07/2006, 23h39

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo