"Si un ouvrier veut bien faire son travail, il doit d'abord affûter ses outils." - Confucius, "Les Entretiens de Confucius. Lu Linggong"
Page de garde > La programmation > Pourquoi la liaison statique de pthread avec g++ entraîne-t-elle une erreur de segmentation, et comment puis-je la résoudre en utilisant l'option « --whole-archive » ?

Pourquoi la liaison statique de pthread avec g++ entraîne-t-elle une erreur de segmentation, et comment puis-je la résoudre en utilisant l'option « --whole-archive » ?

Publié le 2024-11-15
Parcourir:402

Why does statically linking pthread with g   lead to a segmentation fault, and how can I resolve it using the `--whole-archive` option?

Lorsque g lie statiquement pthread, provoquant une erreur de segmentation, pourquoi ?

Dans une liaison statique, l'éditeur de liens s'arrêtera au premier symbole, même s'il est faible, et arrête de chercher des forts. Pour le forcer à examiner tous les symboles (comme il l'aurait fait pour une bibliothèque liée dynamiquement), ld prend en charge l'option --whole-archive.

La commande suivante fonctionnera :

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

Voici ce qui se passe :

  • -pthread implique une liaison avec pthread (et en fonction du plate-forme, il définit des macros supplémentaires comme -D_REENTRANT).
  • Même si -pthread implique une liaison avec -lpthread, vous devez toujours spécifier -lpthread explicitement lors de la liaison statique.
  • Wl,-- Whole-archive force l'éditeur de liens à inclure tous les fichiers objets de l'archive dans le lien, plutôt que de rechercher dans l'archive les fichiers objets requis.
  • Wl,--no-whole-archive désactive l'effet du --option Whole-archive pour les fichiers d'archives suivants.

Comprendre les symboles faibles

Le format de fichier ELF a le concept de symboles faibles et forts. Par défaut, les symboles d'un fichier objet sont forts. Lors de la liaison, un symbole fort peut remplacer un symbole faible du même nom.

Dans le cas de la glibc et des pthreads, ils utilisent des symboles faibles. Par exemple, fputc doit être thread-safe selon POSIX et doit être synchronisé, ce qui est coûteux. Dans un environnement monothread, vous ne voulez pas payer ces coûts. Une implémentation pourrait donc implémenter les fonctions de synchronisation sous forme de stubs vides et déclarer les fonctions comme symboles faibles.

Plus tard, si une bibliothèque multi-thread est liée (par exemple, pthread), il devient évident que la prise en charge d'un seul thread n’est pas prévu. Lors de la liaison de la bibliothèque multi-thread, l'éditeur de liens peut alors remplacer les stubs par les fonctions de synchronisation réelles (définies comme des symboles forts et implémentées par la bibliothèque de threads).

Appliquer ceci à l'exemple de programme

La bibliothèque libc.a contient __pthread_mutex_lock comme symbole faible, et la bibliothèque libpthread.a le contient comme symbole fort. Lors d'une liaison dynamique, l'éditeur de liens remplace le symbole faible par le symbole fort. Cependant, lors d’une liaison statique, vous devez appliquer la même sémantique. C'est pourquoi -Wl,--whole-archive -lpthread -Wl,--no-whole-archive est nécessaire.

Dernier tutoriel Plus>

Clause de non-responsabilité: Toutes les ressources fournies proviennent en partie d'Internet. En cas de violation de vos droits d'auteur ou d'autres droits et intérêts, veuillez expliquer les raisons détaillées et fournir une preuve du droit d'auteur ou des droits et intérêts, puis l'envoyer à l'adresse e-mail : [email protected]. Nous nous en occuperons pour vous dans les plus brefs délais.

Copyright© 2022 湘ICP备2022001581号-3