"Si un trabajador quiere hacer bien su trabajo, primero debe afilar sus herramientas." - Confucio, "Las Analectas de Confucio. Lu Linggong"
Página delantera > Programación > ¿Por qué vincular estáticamente pthread con g++ genera un error de segmentación y cómo puedo resolverlo usando la opción `--whole-archive`?

¿Por qué vincular estáticamente pthread con g++ genera un error de segmentación y cómo puedo resolverlo usando la opción `--whole-archive`?

Publicado el 2024-11-15
Navegar:994

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

Cuando g vincula estáticamente pthread, provocando un error de segmentación, ¿por qué?

En la vinculación estática, el vinculador se detendrá en el primer símbolo, incluso si es débil, y deja de buscar fuertes. Para obligarlo a mirar todos los símbolos (como lo habría hecho para una biblioteca vinculada dinámicamente), ld admite la opción --whole-archive.

El siguiente comando funcionará:

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

Esto es lo que está sucediendo:

  • -pthread implica vincular contra pthread (y dependiendo del plataforma, define macros adicionales como -D_REENTRANT).
  • Incluso si -pthread implica vincular contra -lpthread, aún necesita especificar -lpthread explícitamente mientras vincula estáticamente.
  • Wl,-- el archivo completo obliga al vinculador a incluir todos los archivos objeto del archivo en el enlace, en lugar de buscar en el archivo los archivos objeto requeridos.
  • Wl,--no-whole-archive desactiva el efecto del --opción de archivo completo para archivos posteriores.

Comprender los símbolos débiles

El formato de archivo ELF tiene el concepto de símbolos débiles y fuertes. De forma predeterminada, los símbolos de un archivo objeto son fuertes. Durante la vinculación, un símbolo fuerte puede anular un símbolo débil del mismo nombre.

En el caso de glibc y pthreads, usan símbolos débiles. Por ejemplo, POSIX requiere que fputc sea seguro para subprocesos y debe sincronizarse, lo cual es costoso. En un entorno de un solo subproceso, no querrás pagar estos costos. Por lo tanto, una implementación podría implementar las funciones de sincronización como apéndices vacíos y declarar las funciones como símbolos débiles. no está previsto. Al vincular la biblioteca de subprocesos múltiples, el vinculador puede reemplazar los códigos auxiliares por las funciones de sincronización reales (definidas como símbolos fuertes e implementadas por la biblioteca de subprocesos).

Aplicando esto al programa de ejemplo

La biblioteca libc.a contiene __pthread_mutex_lock como símbolo débil y la biblioteca libpthread.a lo contiene como símbolo fuerte. Al vincular dinámicamente, el vinculador reemplaza el símbolo débil con el símbolo fuerte. Sin embargo, al vincular estáticamente, es necesario aplicar la misma semántica. Es por eso que -Wl,--whole-archive -lpthread -Wl,--no-whole-archive es necesario.

Último tutorial Más>

Descargo de responsabilidad: Todos los recursos proporcionados provienen en parte de Internet. Si existe alguna infracción de sus derechos de autor u otros derechos e intereses, explique los motivos detallados y proporcione pruebas de los derechos de autor o derechos e intereses y luego envíelos al correo electrónico: [email protected]. Lo manejaremos por usted lo antes posible.

Copyright© 2022 湘ICP备2022001581号-3