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

C++ Discussion :

Exception passant à travers les catch


Sujet :

C++

  1. #1
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut Exception passant à travers les catch
    Bonjour,

    Je teste actuellement une application sous Windows et j'ai un petit problème sur ce bout de code :
    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
    try {
              std::cerr << "debut" << std::endl;
              std::cerr.flush();
              boost::filesystem3::copy( path, boost::filesystem3::path("temp_PDF") / path.filename()  );
              std::cerr << "fin" << std::endl;
              std::cerr.flush();
    } catch ( boost::filesystem3::filesystem_error e )
    {
              std::cerr << "except" << std::endl;
             std::cerr.flush();
    } catch ( ... )
    {
             std::cerr << "erreur 1" << std::endl;
             std::cerr.flush();
    }
    catch(...) étant censé, il me semble, pouvoir rattraper toutes les exceptions.
    Ce que je n'arrive pas à m'expliquer, c'est que la ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    boost::filesystem3::copy( path, boost::filesystem3::path("temp_PDF") / path.filename()  );
    lance une exception qui n'est pas attrapée...

    Voici ce que j'ai à l'écran :
    debut
    terminate after throwing an instance of 'boost::filesystem::filesystem_error'
    what() : [...]

    This application has requested the Runtime to terminate it in a unusual way.
    Please contact the application's support team for more information.

    Je ne sais pas si c'est lié mais je ne peux pas lancer mon application deux fois de suite dans la même console DOS ( l'application retourne directement sans rien faire).
    J'ai aussi, quand l'exception n'est pas lancée, un system() qui n'exécute pas la commande passée en argument .

    Est-ce que vous auriez une idée ?

  2. #2
    Membre Expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Par défaut
    Pour l'instant je note juste que tu catch l'exception par copie et je me demande si c'est pas un probleme.

    Sinon, je suis pas specialiste mais il ne se pourait pas qu'il y ait un appel direct a terminate() a cause d'une exception qui se lance dans un catch?

  3. #3
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    par ailleurs, pourquoi flusher après un <<std::endl.

    std::endl fait le flush.

  4. #4
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Citation Envoyé par leternel Voir le message
    par ailleurs, pourquoi flusher après un <<std::endl.

    std::endl fait le flush.
    Malheureusement pas toujours

    Quand on exécute un programme dans la console de QtCreator, le std::endl ne flush pas toujours.
    J'ai donc pris l'habitude de mettre un std::cerr.flush() pour m'éviter toutes mauvaises surprises.

    Pour l'instant je note juste que tu catch l'exception par copie et je me demande si c'est pas un probleme.
    J'attrape le même type d'exceptions sans problème sous Linux, donc je ne pense pas que ce soit ça.
    De plus, même si l'exception n'est pas rattrapée par le premier catch, elle devrait obligatoirement l'être par le second non?


    Sinon, je suis pas specialiste mais il ne se pourait pas qu'il y ait un appel direct a terminate() a cause d'une exception qui se lance dans un catch?
    Il n'y a pas d'exceptions qui se lancent dans un catch ici il me semble non?
    Si la copie est interdite, il devrait théoriquement directement passer au catch suivant.

    J'essaye de passer par référence pour voir ce que cela donne

    EDIT : même en passant par référence constante au lieu de la copie, rien ne change.

  5. #5
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    J'ai oublié de le préciser, mais sous Windows, j'ai fait un :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #define filesystem3 filesystem
    Car sous Windows, filesystem3 n'existe pas.

  6. #6
    Membre Expert
    Homme Profil pro
    Inscrit en
    Décembre 2010
    Messages
    734
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 734
    Par défaut
    Tu linkes en statique ou dynamique? Ca me fait penser à des problèmes d'exceptions qui franchissent des DLL boundaries...

  7. #7
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Les linkages sont en dynamiques (utilisations de .dll)

  8. #8
    Inactif  

    Homme Profil pro
    Ingénieur test de performance
    Inscrit en
    Décembre 2003
    Messages
    1 986
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur test de performance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 986
    Par défaut
    Bonjour.

    Un Debug pas-à-pas, cela dit quoi ? Il semblerai que la biblio Boost joue des coups tordus.

    Avez-vous essayé :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    try {
              std::cerr << "debut" << std::endl;
              std::cerr.flush();
              boost::filesystem3::copy( path, boost::filesystem3::path("temp_PDF") / path.filename()  );
              std::cerr << "fin" << std::endl;
              std::cerr.flush();
    }
    catch ( ... )
    {
             std::cerr << "erreur 1" << std::endl;
             std::cerr.flush();
    }

  9. #9
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Bonjour,

    J'ai essayé avec votre solution mais en mode pas à pas, le résultat est le même, dès qu'on arrive à la ligne de la copie, on quitte directement le programme lors de la copie si le fichier est déjà existant.

    l'exception est lancée dans la méthode "error" de operation.cpp qui lance une exception grâce à la macro BOOST_FILESYSTEM_THROW(EX) qui se contente de faire un throw EX

  10. #10
    Membre Expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Par défaut
    Il faut que tu fasses du pas a pas apres le throw. Je suis presque sur que l'une des conditions pour que terminate() ou abort() soit appele est rencontre.

  11. #11
    Membre Expert
    Homme Profil pro
    Inscrit en
    Décembre 2010
    Messages
    734
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 734
    Par défaut
    Citation Envoyé par Neckara Voir le message
    Bonjour,
    l'exception est lancée dans la méthode "error" de operation.cpp qui lance une exception grâce à la macro BOOST_FILESYSTEM_THROW(EX) qui se contente de faire un throw EX
    Donc ça vient du côté DLL? J'ai remarqué que les exceptions venant de DLL ne sont pas gérables côté appelant dans le cas général (les exceptions cross-boundary marchent si compatibilité binaire parfaite compilé des deux côtés avec le même compilo et les mêmes options).

  12. #12
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Citation Envoyé par Klaim Voir le message
    Il faut que tu fasses du pas a pas apres le throw. Je suis presque sur que l'une des conditions pour que terminate() ou abort() soit appele est rencontre.
    Malheureusement, dès que l'exception est lancée, le programme sort, je ne peux pas aller plus loin.

    Citation Envoyé par therwald Voir le message
    Donc ça vient du côté DLL? J'ai remarqué que les exceptions venant de DLL ne sont pas gérables côté appelant dans le cas général (les exceptions cross-boundary marchent si compatibilité binaire parfaite compilé des deux côtés avec le même compilo et les mêmes options).
    Oui, c'est bien du côté DLL. Pour la compilation, il est possible que ce ne soit pas exactement la même version de mingw ( gcc 4.7.1 vs mingw 4.7.2 peut-être).

    J'essayerais de me générer un makefile pour le compiler avec le gcc installé sous Windows.

  13. #13
    Membre Expert

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Par défaut
    En tout cas le code en soit n'est pas problématique, je l'ai testé directement dans un main avec un path construit par défaut, et l’exception est bien rattrapé. Tu as essayé de compiler en link statique ?

  14. #14
    Membre Expert

    Avatar de germinolegrand
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Octobre 2010
    Messages
    738
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Octobre 2010
    Messages : 738
    Par défaut
    gcc 4.7.1 présente de gros problèmes de compatibilité au niveau de l'ABI.

  15. #15
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    J'ai changé le compilateur pour mon gcc, rien ne change.

    D'après QtCreator, l'ABI serait identique.
    De plus mingw et gcc sont tous les deux à la version 4.7.2 donc le problème semble ne pas venir des compilateurs.

    Après, boost (compilé avec mon gcc) ne "supporte pas officiellement" mingw, le problème pourrait donc venir de là?
    Mais ceci pose pas mal de problèmes si on ne peut plus utiliser d'exceptions

  16. #16
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 391
    Par défaut
    Sous Windows en tout cas, les exceptions n'ont jamais été encouragées cross-DLL. D'où la méthode COM de trapper les exceptions, retourner des HRESULT et des IErrorInfo à la place, et laisser l'appelant relancer l'exception.

    Comme le dit Flob90, as-tu essayé en statique?

    Edit: C'est vraiment très improbable, mais y a-t-il une spécification d'exception dans la déclaration de copy() ?
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  17. #17
    Membre Expert
    Homme Profil pro
    Inscrit en
    Décembre 2010
    Messages
    734
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 734
    Par défaut
    Citation Envoyé par Klaim Voir le message
    Il faut que tu fasses du pas a pas apres le throw. Je suis presque sur que l'une des conditions pour que terminate() ou abort() soit appele est rencontre.
    En fait, je ne pense pas. Quant terminate est appelé suite à double throw, tu ne vois pas le message disant que le programme termine suite à l'exception XXX, il termine, point.
    Comme dit medinoc, quand je veux de la gestion d'exception à travers une DLL boundary, je fais un catch côté DLL, je transmets l'erreur par la valeur de retour, et je rethrow. Quand je peux, j'automatise le rethrow en utilisant un header de DLL qui expose une fonction publique qui le fait. Comme ce code est compilé côté appelant, l'exception est correctmeent gérée par la suite.
    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
     
    struct retour{
     int valeur;
     int codeErreur;
    }
    int function(int parm){
        retour val;
        _functionImpl(pam,&val);
       switch(codeErreur){
          case 0:
             return retour.valeur;
          case 1:
            throw ExceptionType1();
          case 2:
            throw ExceptionType1();
          default:
            throw UnexpectedException();
       }
    };
    void _functionImpl(int parm, retour * retour);
    Ce genre de chose (tu peux raffiner si tu veux sortir plus d'info dans ton exception)

  18. #18
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Sous Windows en tout cas, les exceptions n'ont jamais été encouragées cross-DLL. D'où la méthode COM de trapper les exceptions, retourner des HRESULT et des IErrorInfo à la place, et laisser l'appelant relancer l'exception.
    C'est quand même un comportement ridicule, est-ce qu'ils ont au moins un début de raison de vouloir faire cela ?

    Citation Envoyé par Médinoc Voir le message
    Comme le dit Flob90, as-tu essayé en statique?
    J'ai tenté mais apparemment il faut que je recompile en statique boost. Or je n'ai plus que quelques heures avant de rendre ce projet ( heureusement, les exceptions avec boost ne devraient pas survenir ).

    C'est tout de même problématique, pour un autre projet que je fais, il va donc falloir éviter toutes les exceptions et les lancées qu'au niveau de l'appellant ? ça va être invivable.
    De plus, si je veux utiliser des dll pour permettre des mises à jours plus légère en ne remplaçant que les dll modifiées, je ne pourrais pas compiler en statique.

    Edit: C'est vraiment très improbable, mais y a-t-il une spécification d'exception dans la déclaration de copy() ?
    Vous voulez dire un throw indiqué dans le prototype ? Dans ce cas là non, il n'y a pas de spécification d'exception.

  19. #19
    Membre Expert

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Par défaut
    Tu peux choisir quoi recompiler de boost, et même en prenant tout ce n'est pas si long (typiquement tu le lances et tu continues de réfléchir pendant ce temps).

    Comme autre tests tu pourrais aussi essayer de localiser très exactement le problème et faire un mini-projet qui ne montre que ce problème. Par exemple, compile juste un main avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    #include<iostream>
    #include<boost\filesystem.hpp>
     
    int main(){
        try{
              boost::filesystem::copy(boost::filesystem::path(),boost::filesystem::path());
        } catch (boost::filesystem::filesystem_error e){
            std::cout<<1;
        }
    }
    Et compile le exactement comme ton projet. Tu seras certain que ça vient bien du linkage et pas d'autre chose (tu as pas d'option de compilation exotique qui désactiverait les catch, même indirectement, ou quelque chose du genre ?).

    Edit: Pour l'ABI, normalement c'est même compilateur et même option, sauf indication contraire de compatibilité par ton compilateur. Mais je crois que la spec ABI de gcc est assez large et a une plage de compatibilité assez grande (donc si t'as pas choisit des options étranges, ça doit aller).

  20. #20
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 391
    Par défaut
    Citation Envoyé par Neckara Voir le message
    C'est quand même un comportement ridicule, est-ce qu'ils ont au moins un début de raison de vouloir faire cela ?
    C'est très simple, les DLLs peuvent être écrites et appelées dans différents langages (C++, Visual Basic <= 6.0, et bien plus encore dans le cas de COM), dont les exceptions ne sont pas implémentées de la même manière. Le langage C par exemple, ne sait pas du tout ce qu'est une exception!
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Réponses: 7
    Dernier message: 14/11/2008, 11h49
  2. Pb : Exception / déroutements / try, throw, catch
    Par Bapt_from_Reims dans le forum C++
    Réponses: 5
    Dernier message: 18/03/2005, 17h55
  3. [typedef] protection à travers les espaces de noms
    Par PINGOUIN_GEANT dans le forum C++
    Réponses: 7
    Dernier message: 02/02/2005, 20h21
  4. [Exceptions] Pb avec les exceptions
    Par joquetino dans le forum Langage
    Réponses: 11
    Dernier message: 22/09/2004, 17h08
  5. Copies de flots en passant par les itérateurs
    Par Christophe Brun dans le forum C++
    Réponses: 7
    Dernier message: 02/07/2003, 11h41

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