Maison  >  Article  >  développement back-end  >  Pourquoi mon programme C utilisant « pthread » plante-t-il avec une « erreur de segmentation » lorsqu'il est lié statiquement mais fonctionne correctement lorsqu'il est lié dynamiquement ?

Pourquoi mon programme C utilisant « pthread » plante-t-il avec une « erreur de segmentation » lorsqu'il est lié statiquement mais fonctionne correctement lorsqu'il est lié dynamiquement ?

Linda Hamilton
Linda Hamiltonoriginal
2024-11-02 00:46:02411parcourir

Why does my C   program using `pthread` crash with a

Lorsque g un lien statique pthread provoque une erreur de segmentation, pourquoi ?

Ce programme C, lorsqu'il est lié dynamiquement à l'aide de -pthread -o one one .cpp -Wall -std=c 11 -O3, fonctionne sans aucun problème. Cependant, lorsqu'il est lié statiquement à l'aide de -pthread -o one one.cpp -Wall -std=c 11 -O3 -static, il plante avec une « erreur de segmentation ».

Comprendre le problème

Lors de l'utilisation de -pthread, le compilateur établit automatiquement un lien avec la bibliothèque pthread. Cependant, lors d'une liaison statique, vous devez spécifier explicitement -lpthread pour inclure la bibliothèque pthread.

Symboles faibles

Sous Unix, le format de fichier ELF utilise le concept de symboles faibles, qui peuvent être remplacés par des symboles forts lors de la liaison. La Glibc et pthread utilisent des symboles faibles pour les fonctions qui peuvent éventuellement être remplacées par des versions optimisées.

Dans ce cas, la glibc fournit des symboles faibles pour les fonctions de synchronisation comme __pthread_mutex_lock. Lorsque pthread est lié dynamiquement, les symboles faibles sont remplacés par des symboles forts de pthread.

Lien statique et symboles faibles

Pendant la liaison statique, l'éditeur de liens s'arrêtera au premier symbole qu'il trouve, même s'il s'agit d'un symbole faible. Pour inclure tous les symboles de la bibliothèque pthread, vous devez utiliser l'option Wl,--whole-archive, qui force l'éditeur de liens à inclure tous les fichiers objets de l'archive.

Solution

Pour résoudre le problème, utilisez la commande de liaison suivante :

g++ -o one one.cpp -Wall -std=c++11 -O3 -static -pthread \
    -Wl,--whole-archive -lpthread -Wl,--no-whole-archive

Annexe : Solution de contournement d'Autotools

Si vous utilisez Autotools comme système de build, le La solution de contournement suivante est requise, car Automake n'autorise pas les options dans LDADD :

Dans configure.ac :

WL_WHOLE_ARCHIVE_HACK="-Wl,--whole-archive"
WL_NO_WHOLE_ARCHIVE_HACK="-Wl,--no-whole-archive"
AC_SUBST(WL_WHOLE_ARCHIVE_HACK)
AC_SUBST(WL_NO_WHOLE_ARCHIVE_HACK)

Dans Makefile.am :

mytarget_LDADD = @WL_WHOLE_ARCHIVE_HACK@ -lpthread @WL_NO_WHOLE_ARCHIVE_HACK@

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn