2010-08-04 27 views
7

Sous Linux, j'ai du code C++ généré à partir d'une bibliothèque statique qui définit une variable globale. Une seule instance de cette variable globale est partagée entre deux bibliothèques partagées qui font référence à son symbole.Sur Linux, pourquoi le destructeur s'exécute-t-il deux fois sur une instance partagée de variable globale en C++?

Lorsque le processus s'arrête et que la phase de terminaison statique est exécutée, je vois que le destructeur de cette instance partagée est exécuté deux fois! Vraisemblablement une fois par bibliothèque à chaque déchargement.

Cette question est étroitement liée à une autre que j'ai vu récemment ici: related question. Cela ressemble au même comportement, mais il n'y a pas de discussion sur la raison pour laquelle cela se produit.

Est-ce que quelqu'un connaît l'explication théorique derrière ce comportement?

+0

Il ne doit être exécuté qu'une seule fois par variable par le code généré par le compilateur. Essayez d'obtenir l'adresse de la variable lorsque le destructeur est exécuté pour vérifier qu'il s'agit du même objet. –

+0

Peut-être avez-vous stocké un pointeur sur l'objet dans une classe de pointeurs intelligents, qui tente de détruire son targer. –

+0

Donc le global est défini dans (une unité de compilation de) une seule des bibliothèques? – Thomas

Répondre

2

Si vous prenez un pointeur nu et le placez dans un pointeur intelligent (deux fois), il sera détruit deux fois, une fois pour chaque compte de conteneur tombant à zéro. Donc, si vous passez le pointeur nu dans les deux bibliothèques, cela le ferait. Chacun le met dans un objet pointeur partagé et chacun d'eux fait la destruction. Si vous pouvez voir le backtrace de la pile pendant le dtor, cela devrait se produire dans les deux bibliothèques.

+1

En utilisant n'importe quel débogueur régulier, il devrait être facile de vérifier le backtrace de la pile d'appels et de savoir qui appelle ce destructeur. – Vargas

0

C++ a une règle appelée « Une définition Règle »:

Chaque programme contient exactement une définition de toutes les fonctions non-ligne ou un objet qui est utilisé dans ce programme; aucun diagnostic requis. La définition peut apparaître explicitement dans le programme, elle peut être trouvée dans la bibliothèque standard ou dans une bibliothèque définie par l'utilisateur, ou (le cas échéant) elle est implicitement définie (voir 12.1, 12.4 et 12.8).

Wikipédia a un article qui explique cela plus en détail.

Vous avez pas posté code dans votre question, donc je ne peux pas être sûr de votre cas, mais dans the question you linked to, l'exemple de la question a été de définir la même variable dans deux bibliothèques partagées. Cela a violé la "règle de définition unique", dont dépend apparemment la stratégie de finalisation de l'éditeur de liens dynamiques, ce qui fait que le destructeur est appelé deux fois.