"Se um trabalhador quiser fazer bem o seu trabalho, ele deve primeiro afiar suas ferramentas." - Confúcio, "Os Analectos de Confúcio. Lu Linggong"
Primeira página > Programação > Por que vincular estaticamente pthread com g++ leva a uma falha de segmentação e como posso resolvê-la usando a opção `--whole-archive`?

Por que vincular estaticamente pthread com g++ leva a uma falha de segmentação e como posso resolvê-la usando a opção `--whole-archive`?

Publicado em 15/11/2024
Navegar:930

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

Quando g vincula estaticamente pthread, causando falha de segmentação, por quê?

Na vinculação estática, o vinculador irá parar no primeiro símbolo, mesmo se for fraco, e deixa de procurar os fortes. Para forçá-lo a olhar para todos os símbolos (como teria feito para uma biblioteca vinculada dinamicamente), ld suporta a opção --whole-archive.

O seguinte comando funcionará:

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

Aqui está o que está acontecendo:

  • -pthread implica vinculação ao pthread (e dependendo do plataforma, ele define macros extras como -D_REENTRANT).
  • Mesmo que -pthread implique vinculação a -lpthread, você ainda precisa especificar -lpthread explicitamente ao vincular estaticamente.
  • Wl,--whole-archive força o vinculador a incluir todos os arquivos de objeto no arquivo no link, em vez de pesquisar no arquivo os arquivos de objeto necessários .
  • Wl,--no-whole-archive desativa o efeito da opção --whole-archive para arquivamento subsequente arquivos.

Compreendendo os símbolos fracos

O formato de arquivo ELF tem o conceito de símbolos fracos e fortes. Por padrão, os símbolos em um arquivo objeto são fortes. Durante a vinculação, um símbolo forte pode substituir um símbolo fraco de mesmo nome.

No caso de glibc e pthreads, eles usam símbolos fracos. Por exemplo, o fputc é exigido pelo POSIX para ser thread-safe e precisa ser sincronizado, o que é caro. Em um ambiente de thread único, você não deseja pagar esses custos. Uma implementação poderia, portanto, implementar as funções de sincronização como stubs vazios e declarar as funções como símbolos fracos.

Mais tarde, se uma biblioteca multi-threading estiver vinculada (por exemplo, pthread), torna-se óbvio que o suporte de thread único não se destina. Ao vincular a biblioteca multi-threading, o vinculador pode então substituir os stubs pelas funções de sincronização reais (definidas como símbolos fortes e implementadas pela biblioteca de threading).

Aplicando isso ao programa de exemplo

A biblioteca libc.a contém __pthread_mutex_lock como um símbolo fraco, e a biblioteca libpthread.a contém-o como um símbolo forte. Ao vincular dinamicamente, o vinculador substitui o símbolo fraco pelo símbolo forte. No entanto, ao vincular estaticamente, você precisa impor a mesma semântica. É por isso que -Wl,-whole-archive -lpthread -Wl,--no-whole-archive é necessário.

Tutorial mais recente Mais>

Isenção de responsabilidade: Todos os recursos fornecidos são parcialmente provenientes da Internet. Se houver qualquer violação de seus direitos autorais ou outros direitos e interesses, explique os motivos detalhados e forneça prova de direitos autorais ou direitos e interesses e envie-a para o e-mail: [email protected]. Nós cuidaremos disso para você o mais rápido possível.

Copyright© 2022 湘ICP备2022001581号-3