«Если рабочий хочет хорошо выполнять свою работу, он должен сначала заточить свои инструменты» — Конфуций, «Аналитики Конфуция. Лу Лингун»
титульная страница > программирование > Почему статическое связывание pthread с g++ приводит к ошибке сегментации и как я могу устранить ее с помощью опции `--whole-archive`?

Почему статическое связывание pthread с g++ приводит к ошибке сегментации и как я могу устранить ее с помощью опции `--whole-archive`?

Опубликовано 15 ноября 2024 г.
Просматривать:650

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

Когда g статически связывает поток pthread, вызывая ошибку сегментации, почему?

При статическом связывании компоновщик останавливается даже на первом символе если он слабый, и перестает искать сильных. Чтобы заставить его просмотреть все символы (как это было бы сделано для динамически подключаемой библиотеки), ld поддерживает опцию --whole-archive.

Следующая команда будет работать:

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

Вот что происходит:

  • -pthread подразумевает связывание с pthread (и в зависимости от платформа, она определяет дополнительные макросы, такие как -D_REENTRANT).
  • Даже если -pthread подразумевает связывание с -lpthread, вам все равно необходимо явно указать -lpthread при статическом связывании.
  • Wl,-- Whole-archive заставляет компоновщик включать каждый объектный файл в архиве в ссылку, вместо того, чтобы искать в архиве необходимые объектные файлы.
  • Wl, --no-whole-archive отключает эффект Опция --whole-archive для последующих файлов архива.

Понимание слабых символов

Формат файлов ELF имеет концепцию слабых и сильных символов. По умолчанию символы в объектном файле являются сильными. Во время связывания сильный символ может переопределить слабый символ с тем же именем.

В случае glibc и pthreads они используют слабые символы. Например, POSIX требует, чтобы fputc был потокобезопасным и его необходимо синхронизировать, что требует больших затрат. В однопоточной среде вам не придется нести эти расходы. Таким образом, реализация может реализовать функции синхронизации как пустые заглушки и объявить функции как слабые символы.

Позже, если связана многопоточная библиотека (например, pthread), становится очевидным, что поддержка однопоточной обработки не предназначено. При связывании многопоточной библиотеки компоновщик может затем заменить заглушки реальными функциями синхронизации (определенными как строгие символы и реализованными библиотекой потоков).

Применение этого к примеру программы

Библиотека libc.a содержит __pthread_mutex_lock как слабый символ, а библиотека libpthread.a содержит его как сильный символ. При динамическом связывании компоновщик заменяет слабый символ сильным символом. Однако при статическом связывании вам необходимо обеспечить ту же семантику. Вот почему нужен -Wl,--whole-archive -lpthread -Wl,--no-whole-archive.

Последний учебник Более>

Изучайте китайский

Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.

Copyright© 2022 湘ICP备2022001581号-3