2009-06-17 6 views
4

J'ai un programme de test appelé ftest. Il charge les fichiers .so contenant des tests et exécute les tests qu'il trouve. Un de ces tests charge et exécute un .so qui contient un pilote de base de données Postgres pour notre O/RM. Lorsque le pilote Postgres renvoie une exception qui est définie dans ce fichier .so (ou auquel il est lié mais que le lien ftest ne pointe pas) et est intercepté par l'infrastructure de test, le destructeur d'exceptions déclenche un segfault.Exceptions sous Linux à partir d'un objet partagé (.so)

Cette segfault se produit lorsque l'exception compilée se trouve dans un fichier .so qui a été chargé dynamiquement (en utilisant dload).

Ce genre de chose fonctionne très bien dans Windows qui a la même architecture. Nous ne souhaitons pas vraiment nous limiter à utiliser uniquement les exceptions provenant des bibliothèques principales. Les compléments devraient être libres de créer leurs propres classes d'exceptions et de les gérer normalement.

Les exceptions sont les sous-classes de std :: exception. Parfois, les exceptions peuvent être définies dans des bibliothèques (telles que libpqxx), ce qui signifie que les exceptions sont parfois hors de notre contrôle.

exceptions sont levées en utilisant quelque chose comme:

throw exception_class(exception_arguments); 

Et sont capturés à l'aide:

catch (std::exception &e) { 
    // handler code 
} 

Yat-il une option de compilateur spécial nécessaire pour obtenir ce travail? Avons-nous besoin de passer à des exceptions via throw new exception_class(args) (nous ne voulons pas vraiment faire cela)?

Répondre

6

En supposant que votre gcc -

Append -Wl, -E lorsque vous créez le dlload appelant exécutable(). Cela exporte tous les symboles d'informations de type à partir de l'exécutable, ce qui devrait permettre au RTTI (lors de la capture de l'exception) de fonctionner correctement. VC++ utilise une comparaison de chaînes pour correspondre à typeinfo, ce qui entraîne un ralentissement de dynamic_cast <> etc mais des binaires plus petits. g ++ utilise le pointeur compare.

J'ai rencontré le même problème lors de la tentative d'utilisation de classes d'interfaces virtuelles pures implémentées dans un fichier .so chargé au moment de l'exécution.

Il y a aussi quelques articles sur le sujet flottant sur le net.

espérons que cela aide, Hayman.

+0

C'est en fait le destructeur qui a le problème et non le piège. Je ne serais pas surpris si c'est l'emplacement de la table virtuelle cependant - peut-être que le .so ne donne pas l'autorisation de lecture sur la page où la table est chargée afin que le destructeur ne puisse pas être lu. C'est de la pure spéculation cependant. Je vais voir si je peux trouver comment configurer ces options via Boost.Build. – KayEss

+0

-Wl, E ne semble pas avoir fait la différence :( – KayEss

+0

En fait, je pense que le -Wl, E a eu un effet - il y avait un deuxième problème où les exceptions faisaient également le .so décharger avant que l'exception avait En corrigeant ces deux moyens, nous obtenons maintenant que les exceptions fonctionnent sans segfaults. – KayEss

Questions connexes