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 ?
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!