OVH Cloud OVH Cloud

GCC 3.2 : abort sur exceptions C++

3 réponses
Avatar
ChessManiac
Bonjour,


J'ai le probl=E8me suivant en ex=E9cutant un programme C++ link=E9 avec u=
ne
librairie dynamique (LIB) dont je n'ai pas la ma=EEtrise :

=3D> Lorsque mon main appelle une m=E9thode "Meth" de LIB qui normalement=

g=E9n=E8re une exception "Exc", GCC plante le programme (Abort)
*avant* que le catch ne soit ex=E9cut=E9. Mon bout de code :

> try {
> toto->Meth();
> }
> catch (LIB::Exc &e) {
> cout << "Exception r=E9cup=E9r=E9e" << endl;
> }
> catch (const std::exception& x) {
> cerr << "Error : UNKNOWN STD EXCEPTION" << endl;
> }
> catch (...) {
> cerr << "Error : UNKNOWN EXCEPTION" << endl;
> }

Au d=E9bugger on voit la chose suivante dans la pile d'appel :

> 0x4092b721 in kill () from /lib/libc.so.6
> #1 0x4043c771 in pthread_kill () from /lib/libpthread.so.0
> #2 0x4043ca7b in raise () from /lib/libpthread.so.0
> #3 0x4092b4d4 in raise () from /lib/libc.so.6
> #4 0x4092c9e8 in abort () from /lib/libc.so.6
> #5 0x408b2ba7 in __cxxabiv1::__terminate(void (*)()) (handler=3D0x409=
2c870 <abort>) at ../../../../gcc-3.2.2/libstdc++-v3/libsupc++/eh_termina=
te.cc:47
> /opt/src/gcc-3.2.2/libstdc++-v3/libsupc++/eh_terminate.cc:47:1856:beg:=
0x408b2ba7
> #6 0x408b2bf4 in std::terminate() () at ../../../../gcc-3.2.2/libstdc=
++-v3/libsupc++/eh_terminate.cc:57
> #7 0x408b2d76 in __cxa_throw () at ../../../../gcc-3.2.2/libstdc++-v3=
/libsupc++/eh_throw.cc:77
> /opt/src/gcc-3.2.2/libstdc++-v3/libsupc++/eh_throw.cc:77:2810:beg:0x40=
8b2d76
> #8 0x4028da68 in DtFederateMgr::testReadFedFile(RtiDtString, RtiDtStr=
ing) () from libLIB.so
> ..... etc

On voir que dans eh_throw.cc, GCC ne lance pas d'exception mais au contra=
ire
appelle terminate !

J'ai vu sur le net que d'autres personnes ont eu des probl=E8mes analogue=
s
mais je n'ai trouv=E9 aucune r=E9ponse satisfaisante =E0 ce probl=E8me.
Si quelqu'un a une id=E9e ..... merci d'avance ...


Le contexte (qui peut avoir son importance) :

- compilation avec g++ (GCC 3.2.2) sous Linux Debian Woody
- j'ai essay=E9 plein de trucs, notamment compiler avec -fexceptions, -pt=
hread, -shared
-DTHREAD, -DPTHREADS, -DREENTRANT
linker avec -lstdc++, -lpthread,
tout =E7a sans succ=E8s

3 réponses

Avatar
Christophe de VIENNE
ChessManiac wrote:
Bonjour,


J'ai le problème suivant en exécutant un programme C++ linké avec une
librairie dynamique (LIB) dont je n'ai pas la maîtrise :

=> Lorsque mon main appelle une méthode "Meth" de LIB qui normalement
génère une exception "Exc", GCC plante le programme (Abort)
*avant* que le catch ne soit exécuté. Mon bout de code :



hmmm que de bons souvenirs.... J'ai eu exactement le même problème avec
mon application lorsque je suis passé de gcc 2.95.x à gcc 3.x.
Je me rappelle avoir passé plusieurs jours à tout essayé sans succès, et
ce malgré l'aide de Gaby.

Cela dit en trifouillant j'ai fini par ne plus l'avoir, mais je ne sais
pas exactement la raison.
Quelques pistes néammoins, potentiellement farfelues, et sans aucunes
garanties :
- Est-ce que ton programme et la bibliothèque ont été compilé avec
exactement la même version du compilateur ? D'après ce que j'ai compris
dans certain cas, les identifiants RTTI attendu par le programme et ceux
générés par la bibliothèque sont différents.
- Essayes de changer l'ordre des bibliothèques sur la ligne de commande
du link, voir même en mettant plusieurs fois celle qui pose problème.
- As-tu récemment mis à jour ta glibc, sans rebooter ?


Voilà, c'est tout ce que je peux faire pour l'instant...

A+

Christophe

Avatar
ChessManiac
ChessManiac wrote:

Bonjour,


J'ai le problème suivant en exécutant un programme C++ linké avec une
librairie dynamique (LIB) dont je n'ai pas la maîtrise :

=> Lorsque mon main appelle une méthode "Meth" de LIB qui normalement
génère une exception "Exc", GCC plante le programme (Abort)
*avant* que le catch ne soit exécuté. Mon bout de code :



hmmm que de bons souvenirs.... J'ai eu exactement le même problème avec
mon application lorsque je suis passé de gcc 2.95.x à gcc 3.x.
Je me rappelle avoir passé plusieurs jours à tout essayé sans succès, et
ce malgré l'aide de Gaby.

Cela dit en trifouillant j'ai fini par ne plus l'avoir, mais je ne sais
pas exactement la raison.
Quelques pistes néammoins, potentiellement farfelues, et sans aucunes
garanties :
- Est-ce que ton programme et la bibliothèque ont été compilé avec
exactement la même version du compilateur ? D'après ce que j'ai compris
dans certain cas, les identifiants RTTI attendu par le programme et ceux
générés par la bibliothèque sont différents.
- Essayes de changer l'ordre des bibliothèques sur la ligne de commande
du link, voir même en mettant plusieurs fois celle qui pose problème.
- As-tu récemment mis à jour ta glibc, sans rebooter ?


Christophe,

Merci pour ta réponse ... j'avais trouvé tes échanges de
questions/réponses avec Gaby sur le net :-)

Effectivement je cumule les handicaps :
- la librairie est générée sur Red Hat (mais la même version du GCC)
alors que je suis en Debian
- cette Debian a été "upgradée" avec une glibc2.3 (à l'origine c'est
une glibc2.2), par contre il y a eu reboot

Je vais essayer de changer l'ordre des "-l" lors du link.
Peux-tu aussi me dire ce que sont les identifiants RTTI ?


Avatar
Christophe de VIENNE
ChessManiac wrote:

ChessManiac wrote:

Bonjour,


J'ai le problème suivant en exécutant un programme C++ linké avec une
librairie dynamique (LIB) dont je n'ai pas la maîtrise :

=> Lorsque mon main appelle une méthode "Meth" de LIB qui normalement
génère une exception "Exc", GCC plante le programme (Abort)
*avant* que le catch ne soit exécuté. Mon bout de code :



hmmm que de bons souvenirs.... J'ai eu exactement le même problème
avec mon application lorsque je suis passé de gcc 2.95.x à gcc 3.x.
Je me rappelle avoir passé plusieurs jours à tout essayé sans succès,
et ce malgré l'aide de Gaby.

Cela dit en trifouillant j'ai fini par ne plus l'avoir, mais je ne
sais pas exactement la raison.
Quelques pistes néammoins, potentiellement farfelues, et sans aucunes
garanties :
- Est-ce que ton programme et la bibliothèque ont été compilé avec
exactement la même version du compilateur ? D'après ce que j'ai
compris dans certain cas, les identifiants RTTI attendu par le
programme et ceux générés par la bibliothèque sont différents.
- Essayes de changer l'ordre des bibliothèques sur la ligne de
commande du link, voir même en mettant plusieurs fois celle qui pose
problème.
- As-tu récemment mis à jour ta glibc, sans rebooter ?



Christophe,

Merci pour ta réponse ... j'avais trouvé tes échanges de
questions/réponses avec Gaby sur le net :-)

Effectivement je cumule les handicaps :
- la librairie est générée sur Red Hat (mais la même version du GCC)
alors que je suis en Debian
- cette Debian a été "upgradée" avec une glibc2.3 (à l'origine c'est
une glibc2.2), par contre il y a eu reboot

Je vais essayer de changer l'ordre des "-l" lors du link.
Peux-tu aussi me dire ce que sont les identifiants RTTI ?


RunTime Type Information. C'est le mécanisme qui permet l'identification
d'un type de données à l'exécution. Il est utilisé pour le
fonctionnement des exceptions : c'est grâce à lui que les exceptions
s'"arrêtent" dans le bon bloc catch. Si l'identifiant de ton exception
généré (à la compilation) par le compilateur de la lib est différent de
celui déterminé par le compilateur du programme, tout se passera comme
si tu n'avais aucun catch interceptant ton exception, c'est à dire un
joli abort comme tu l'as...

Si ton application n'est pas trop imposante, il serait très interessant
que tu reproduises le problème en plus petit (perso j'ai pas réussi).
Comme ça on aurait des infos plus précises que mes conjectures
hasardeuses :-)


A+

Christophe