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:
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!