Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Mengapakah pautan pthread secara statik dengan g membawa kepada kesalahan pembahagian dan bagaimana saya boleh menyelesaikannya menggunakan pilihan `--keseluruhan-arkib`?

Mengapakah pautan pthread secara statik dengan g membawa kepada kesalahan pembahagian dan bagaimana saya boleh menyelesaikannya menggunakan pilihan `--keseluruhan-arkib`?

Barbara Streisand
Barbara Streisandasal
2024-10-27 01:57:02450semak imbas

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

Apabila g memaut pthread secara statik, menyebabkan kerosakan Segmentasi, mengapa?

Dalam pemautan statik, pemaut akan berhenti pada simbol pertama, walaupun jika ia lemah, dan berhenti mencari yang kuat. Untuk memaksanya melihat semua simbol (seperti yang akan dilakukan untuk perpustakaan yang dipautkan secara dinamik), ld menyokong pilihan --whole-archive.

Arahan berikut akan berfungsi:

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

Berikut ialah perkara yang berlaku:

  • -pthread membayangkan pemautan terhadap pthread (dan bergantung pada platform, ia mentakrifkan makro tambahan seperti -D_REENTRANT).
  • Walaupun -pthread membayangkan pemautan terhadap -lpthread, anda masih perlu menentukan -lpthread secara eksplisit semasa memaut secara statik.
  • Wl,--whole-archive memaksa pemaut untuk memasukkan setiap fail objek dalam arkib dalam pautan, dan bukannya mencari arkib untuk fail objek yang diperlukan.
  • Wl,--no-whole-archive mematikan kesan pilihan --whole-archive untuk fail arkib seterusnya.

Pemahaman simbol lemah

Format fail ELF berkonsepkan simbol lemah dan kuat. Secara lalai, simbol dalam fail objek adalah kuat. Semasa memaut, simbol kuat boleh mengatasi simbol lemah dengan nama yang sama.

Dalam kes glibc dan pthread, ia menggunakan simbol lemah. Sebagai contoh, fputc diperlukan oleh POSIX supaya selamat untuk benang dan perlu disegerakkan, yang memerlukan kos yang tinggi. Dalam persekitaran satu benang, anda tidak mahu membayar kos ini. Oleh itu, pelaksanaan boleh melaksanakan fungsi penyegerakan sebagai stub kosong dan mengisytiharkan fungsi sebagai simbol lemah.

Kemudian, jika perpustakaan berbilang benang dipautkan (cth., pthread), ia menjadi jelas bahawa sokongan satu benang tidak dimaksudkan. Apabila memautkan pustaka berbilang benang, pemaut kemudiannya boleh menggantikan stub dengan fungsi penyegerakan sebenar (ditakrifkan sebagai simbol kuat dan dilaksanakan oleh pustaka benang).

Menggunakan ini pada program contoh

Pustaka libc.a mengandungi __pthread_mutex_lock sebagai simbol lemah dan perpustakaan libpthread.a mengandunginya sebagai simbol kuat. Apabila memaut secara dinamik, pemaut menggantikan simbol lemah dengan simbol kuat. Walau bagaimanapun, apabila memaut secara statik, anda perlu menguatkuasakan semantik yang sama. Itulah sebabnya -Wl,--keseluruhan-arkib -lpthread -Wl,--tiada-keseluruhan-arkib diperlukan.

Atas ialah kandungan terperinci Mengapakah pautan pthread secara statik dengan g membawa kepada kesalahan pembahagian dan bagaimana saya boleh menyelesaikannya menggunakan pilihan `--keseluruhan-arkib`?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn