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

Multithreading Discussion :

QThread et Exception (MinGW => crash & VC9 => First-chance)


Sujet :

Multithreading

  1. #1
    Membre habitué
    Inscrit en
    Juin 2003
    Messages
    223
    Détails du profil
    Informations personnelles :
    Âge : 40

    Informations forums :
    Inscription : Juin 2003
    Messages : 223
    Points : 145
    Points
    145
    Par défaut QThread et Exception (MinGW => crash & VC9 => First-chance)
    Bonjour,

    alors voici mon problème

    Durant l'exécution du QThread::run() il arrive qu'un exception soit lancée par une librairie tierce (OpenCV).

    Avec MinGW (GCC 4.4) j'obtiens:


    Un segmentation fault apres avoir executer le catch de mon exception:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    Thread [2] (Suspended: Signal 'SIGSEGV' received. Description: Segmentation fault.)	
    	13 read_encoded_value_with_base()  0x00403cf6	
    	12 parse_lsda_header()  0x00403e03	
    	11 __gxx_personality_sj0()  0x004041a2	
    	10 _Unwind_SjLj_RaiseException() ..\..\..\..\gcc-4.4.1\gcc\unwind.inc:113 0x00409080	
    	9 __cxa_throw()  0x00404d6a	
    	8 OtherThread::run()  0x00402c95	
    	7 ZN7QThread11setPriorityENS_8PriorityE()  0x6a1d68be	
    	6 msvcrt!_itow_s()  0x75e61287	
    	5 msvcrt!_endthreadex()  0x75e61328	
    	4 KERNEL32!AcquireSRWLockExclusive()  0x75dc1194	
    	3 ntdll!RtlInsertElementGenericTableAvl()  0x7795b3f5	
    	2 ntdll!RtlInsertElementGenericTableAvl()  0x7795b3c8	
    	1 <symbol is not available> 0x00000000

    Avec VisualStudio 2008 J'obtiens:


    First-chance exception at 0x75cd9617 in exTest.exe: Microsoft C++ exception: char at memory location 0x0646fa64.
    (Je ne suis pas sur que cela soit grave mais j'aimerais savoir pourquoi ce message est affiché)

    Application type:

    J'ai donc écris ce matin une application qui simule le comportement de mon programme et de comment attraper les exceptions dans un QThread, voici le code du QThread (le reste se trouve dans le fichiers joints)

    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
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
     
    #include "OtherThread.h"
    #include <qDebug>
    #include <cstdio>
    #include "Errors.h"
     
    #ifdef USE_OPENCV
    #include <cv.h>
    #endif
     
     
    int OtherThread::count=0;
     
    enum
    {
    	EXC_NONE=0,
    	EXC_CLASSIC,
    	EXC_STD,
    	EXC_CVINTERN,
    	EXC_CVEXTERN,
    };
     
     
    OtherThread::OtherThread(QObject *parent, QComboBox *eType_, QSpinBox *wait_, QCheckBox *checkBox_)
    :QThread(parent), life(true), cbEType(eType_), spWaitTime(wait_), cbStop(checkBox_)
    {
    	count++;
    	ID=count;
    }
     
     
    void OtherThread::stop()
    {
    	if(isRunning())
    	{
    		life=false;
    		wait();
    	}
    	else
    	{
    		throw "Can not stop a not running thread";
    	}
    }
     
     
    void OtherThread::run()
    {
    	MY_FUNCNAME("OtherThread::run()")
     
     
    	int waitTime=spWaitTime->value();
    	int eType=cbEType->currentIndex();
    	bool catchStop = cbStop->isChecked();
    	int count=1, countMax=100;
    	char msg[50];
    	sprintf(msg,"#%d: Generate an error",ID);
     
     
    	qDebug() << "#"<<ID<<": Start => " << waitTime << " (ms), " << eType;
     
     
    	while(life)
    	{
    		qDebug() << "#"<<ID<<" => "<< count%countMax <<"  ("<<count<<")";
     
     
    		try
    		{
    			if(count%countMax==0)
    			{
    				if(eType==EXC_NONE)
    				{
    					qDebug() << "No exception thrown";
    				}
    				else if(eType==EXC_CLASSIC)
    				{
    					throw "classic exception";
    				}
    				else if(eType==EXC_STD)
    				{
    					std::vector<int> tab( 10 );
    					tab.at( 10 );	//Access to 11th elements
    				}
    				else if(eType==EXC_CVINTERN)
    				{
    					MY_ERROR(msg);
    				}
    				else if(eType==EXC_CVEXTERN)
    				{
    #ifdef USE_OPENCV
    					IplImage *src=cvCreateImage(cvSize(200,200),IPL_DEPTH_8U,3);
    					src->imageData=0;
    					cvSet(src,cvScalarAll(0));
    #else
    					throw "OpenCV extern is not defined";
    #endif
    				}
    				else
    				{
    					throw -1;
    				}
    			}
    		}
    		catch(const std::exception& e)
    		{
    			fprintf(stderr,"#%d: %s\n",ID,e.what());
    			fflush(stderr);
    			if(catchStop) stop();
    		}
    		catch(char * str)
    		{
    			fprintf(stderr,"#%d: %s\n",ID,str);
    			fflush(stderr);
    			if(catchStop) stop();
    		}
    		catch(...)
    		{
    			fprintf(stderr,"#%d: Unknown Error\n", ID);
    			fflush(stderr);
    			if(catchStop) stop();
    		}
     
    		msleep(waitTime);
    		count++;
    	}
     
    	qDebug() << "#"<<ID<<": Stop!!!!!!!!";
    }
    J'ai mis le projet entier avec le reste du code dans le fichier zip ci-joint.
    J'utilise CMake afin de générer le projet. OpenCV n'est lui pas nécessaire, mais peu etre inclus dans la compilation.

    Merci d'avance!
    Fichiers attachés Fichiers attachés

  2. #2
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut
    Si tu utilise VisualStudio, que te donne le debuggeur? il est beaucoup plus explicite que gdb.

    Sinon, à la vue de tes catch je dirais soit c'est à cause de soit :
    1. fprintf et fflush qui sont rarement thread safe.
    2. de l'appel de la fonction stop qui appel wait.


    Je parie sur la deux vois tu pourquoi?

  3. #3
    Membre habitué
    Inscrit en
    Juin 2003
    Messages
    223
    Détails du profil
    Informations personnelles :
    Âge : 40

    Informations forums :
    Inscription : Juin 2003
    Messages : 223
    Points : 145
    Points
    145
    Par défaut
    Si tu utilise VisualStudio, que te donne le debuggeur? il est beaucoup plus explicite que gdb.
    Bein ca me donne rien de spécial car le crash est produit seulement avec MinGW.
    Sous visual le seul problème est ce message d'erreur bizarre. J'ai regardé sur internet et certain disent que ce n'est pas un message important, d'autre disent qu'il faut résoudre ce warning.


    fprintf et fflush qui sont rarement thread safe.
    Que me conseil tu? Il y a t'il des fonctions standards (C99) qui me permettent de faire un fprintf dans un thread?


    que l'appel de la fonction stop qui appel wait
    Le stop n'est pas le problème (Car j'ai l'option catchStop qui me permet de le desactivé) ... mais tu as raison je devrais juste mettre la variable life=false; et ne pas appeler la fonction stop dans le thread.

  4. #4
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut
    Citation Envoyé par elraton Voir le message
    Que me conseil tu? Il y a t'il des fonctions standards (C99) qui me permettent de faire un fprintf dans un thread?
    Regarde qDebug() & co

    Citation Envoyé par elraton Voir le message
    Le stop n'est pas le problème (Car j'ai l'option catchStop qui me permet de le desactivé) ... mais tu as raison je devrais juste mettre la variable life=false; et ne pas appeler la fonction stop dans le thread.
    Ca ne te choque pas qu'un thread utilise wait pour savoir quand il est fini?
    D'ailleur comment peut il se terminer s'il attend d'être terminer pour se terminer?

  5. #5
    Membre habitué
    Inscrit en
    Juin 2003
    Messages
    223
    Détails du profil
    Informations personnelles :
    Âge : 40

    Informations forums :
    Inscription : Juin 2003
    Messages : 223
    Points : 145
    Points
    145
    Par défaut
    Bon j'ai donc changé le code de OtherThread.cpp:

    • j'ai mis qWarning() au lieu de fprintf()
    • J'ai enlevé le wait (qui était en effet une tres mauvaise idée), pour le remplacer par life=false.



    Malheureusement j'obtiens toujours le même crash (sous MinGW), et la meme erreurs en utilisant Visual Studio 2008

  6. #6
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut
    Un bon petit pas à pas avec quelquse break points et voici le résultat

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    std::vector<int> tab( 10 );
    tab.at( 10 );	//Access to 11th elements
    Tu as un tableau de taille 10 et ru accède au 11 ième élément => erreur
    mingw == erreur mémoire
    VC == exception + avertissement sur la console.

  7. #7
    Membre habitué
    Inscrit en
    Juin 2003
    Messages
    223
    Détails du profil
    Informations personnelles :
    Âge : 40

    Informations forums :
    Inscription : Juin 2003
    Messages : 223
    Points : 145
    Points
    145
    Par défaut
    Ouais je sais que l'erreur vient de la! Si le programme est un générateur d'erreur dans différents Threads.

    Mon problème c'est que je n'arrive pas a gérer l'exception lancé sous MinGW, que celle-ci soit lancée depuis la STL (accès a une position non réservée d'un vecteur), depuis OpenCV (Accès a une image n'ayant pas de pointeur sur les données), ou lancée depuis le programme lui même avec mon propre throw.

    MinGW devrait pouvoir attraper l'exception correctement et stopper le thread sans que les autres threads soit interrompus.

  8. #8
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut
    Pour le message "First chance exception" : http://blogs.msdn.com/b/davidklinems...12/438061.aspx

    Pour le crash mingw, j'ai peut être parlé trop vite Le at est bien sensé émettre une exception. Quand tu compile avec mingw, tu est bien en debug?

    [edit]
    si tu enlève cette partie ca donne quoi?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    int waitTime=spWaitTime->value();
    int eType=cbEType->currentIndex();
    bool catchStop = cbStop->isChecked();

  9. #9
    Membre habitué
    Inscrit en
    Juin 2003
    Messages
    223
    Détails du profil
    Informations personnelles :
    Âge : 40

    Informations forums :
    Inscription : Juin 2003
    Messages : 223
    Points : 145
    Points
    145
    Par défaut
    Mon code est bien de Debug!!!

    Voici un bout de la compilation:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    [ 66%] Building CXX object CMakeFiles/exTest.dir/src/OtherThread.cpp.obj
    C:\MinGW\bin\g++.exe   -DUSE_OPENCV -DQT_DLL -DQT_GUI_LIB -DQT_CORE_LIB -fexceptions -mthreads -g -IC:\Libs\OpenCV\2.x\MinGW -IC:\Libs\OpenCV\trunk\include -IC:\Libs\OpenCV\trunk\include\opencv -IC:\Libs\Qt\4.6\include -IC:\Libs\Qt\4.6\include\QtGui -IC:\Libs\Qt\4.6\include\QtCore -IC:\Users\Ben\project\exThread\builds\ecDbg   -o CMakeFiles\exTest.dir\src\OtherThread.cpp.obj -c C:\Users\Ben\project\exThread\scm\src\OtherThread.cpp

    Pour le bout de code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    int waitTime=spWaitTime->value();
    int eType=cbEType->currentIndex();
    bool catchStop = cbStop->isChecked();
    Ce n'est pas le problème au début c'était des valeur fixe, maintenant je lit juste ces valeurs depuis une GUI avant de lancer le thread.

  10. #10
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut
    Citation Envoyé par elraton Voir le message
    Ce n'est pas le problème au début c'était des valeur fixe, maintenant je lit juste ces valeurs depuis une GUI avant de lancer le thread.
    Ok mais ça peut en poser un. Il ne faut pas faire cela. Un QObject ne doit pas être utiliser par plusieurs thread.

    Pour ton cas, je n'ai pas trop d'idée. Si j'ai bien compris, c'est bien le at qui te fait planter l'application? c'est ce que tu as vérifié?

  11. #11
    Membre habitué
    Inscrit en
    Juin 2003
    Messages
    223
    Détails du profil
    Informations personnelles :
    Âge : 40

    Informations forums :
    Inscription : Juin 2003
    Messages : 223
    Points : 145
    Points
    145
    Par défaut
    Ouais je sais c'est pas terrible mais comme c'est juste une lecture au début de Thread ce n'est pas très grave.

    Bein, le problème c'est que des qu'il y a une exception qui apparait cela plante mon programme quand je l'attrape (catch), alors qu'il faudrait que je puisse lire cette exception et écrire un message d'erreur dans mon programme.

  12. #12
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut
    Je viens de tester ton zip avec le dernier sdk.
    Donc mingw 4.4 et Qt 4.6.3.

    Aucun problème... Tous est bien catché.

  13. #13
    Membre habitué
    Inscrit en
    Juin 2003
    Messages
    223
    Détails du profil
    Informations personnelles :
    Âge : 40

    Informations forums :
    Inscription : Juin 2003
    Messages : 223
    Points : 145
    Points
    145
    Par défaut
    Quels version de MinGW utilises tu? (Officiel, TDM-SjLj, Dwarf)
    Pour Qt 4.6.3, tu utilises les fichiers binaires officiels (http://get.qt.nokia.com/qt/source/qt....1-mingw.exe)? Ou tu as compilé toi même Qt?

    Je vais tester avec la même config que toi pour voir d'ou viens le problème !!!

  14. #14
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut
    j'ai telechargé le dernier Qt sdk. QUi contient tous ce qu'il faut. QtCreator, mingw et Qt 4.6.3.

  15. #15
    Membre habitué
    Inscrit en
    Juin 2003
    Messages
    223
    Détails du profil
    Informations personnelles :
    Âge : 40

    Informations forums :
    Inscription : Juin 2003
    Messages : 223
    Points : 145
    Points
    145
    Par défaut
    Okay visiblement ca marche mieux mais maintenant le problème vient le la librairies externe:

    OpenCV me fait toujours planter mon application!
    Donc ca a avancer un peu mais c'est toujours pas top! Je continue mes recherches!!!!

Discussions similaires

  1. web service :A first chance exception..
    Par yan dans le forum Windows Mobile
    Réponses: 1
    Dernier message: 05/06/2009, 22h58
  2. Réponses: 2
    Dernier message: 27/06/2008, 16h03
  3. First Chance Exception
    Par Moustico dans le forum C#
    Réponses: 2
    Dernier message: 10/12/2007, 16h00
  4. Réponses: 18
    Dernier message: 09/10/2007, 10h20
  5. Réponses: 8
    Dernier message: 16/06/2005, 13h58

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