Ini adalah pertanyaan bekas dari situs pengembangan OS, tetapi membuat saya penasaran karena saya tidak dapat menemukan penjelasan yang layak di mana pun.
Saat mengompilasi dan menautkan program C ++ yang berdiri sendiri menggunakan gcc, terkadang kesalahan penaut seperti ini terjadi:
out/kernel.o:(.eh_frame+0x11): undefined reference to `__gxx_personality_v0'
Ini tampaknya karena simbol ini didefinisikan di libstdc ++, yang tidak ada di lingkungan yang berdiri sendiri. Memperbaiki masalah hanya perlu mendefinisikan simbol ini di suatu tempat:
void *__gxx_personality_v0;
Mana yang bagus, tapi saya tidak suka hal-hal yang bekerja secara ajaib ... Jadi pertanyaannya adalah, apa tujuan dari simbol ini?
-fno-exceptions
. Saya menambahkanCPPFLAGS += -fno-exceptions
ke makefile saya, dan itu menyelesaikan kesalahan.Itu bagian dari penanganan pengecualian. Mekanisme gcc EH memungkinkan untuk mencampur berbagai model EH, dan rutinitas kepribadian dipanggil untuk menentukan apakah pengecualian cocok, finalisasi apa yang akan dipanggil, dll. Rutinitas kepribadian khusus ini untuk penanganan pengecualian C ++ (sebagai lawan, katakanlah, gcj / Java penanganan pengecualian).
sumber
Penanganan pengecualian termasuk dalam implementasi berdiri bebas.
Alasannya adalah bahwa Anda mungkin menggunakan
gcc
untuk mengkompilasi kode Anda. Jika Anda mengkompilasi dengan opsi,-###
Anda akan melihat opsi linker hilang-lstdc++
saat menjalankan proses linker. Mengompilasi dengang++
akan menyertakan pustaka itu, dan dengan demikian simbol yang ditentukan di dalamnya.sumber
file.cpp
with,gcc
bukang++
?libstdc++
adalah satu-satunya perbedaan antara keduanya.Sebuah grep cepat dari
libstd++
basis kode mengungkapkan dua penggunaan berikut__gx_personality_v0
:Di libsupc ++ / unwind-cxx.h
Di libsupc ++ / eh_personality.cc
(Catatan: ini sebenarnya sedikit lebih rumit dari itu; ada beberapa kompilasi bersyarat yang dapat mengubah beberapa detail).
Jadi, selama kode Anda tidak benar-benar menggunakan penanganan pengecualian, mendefinisikan simbol sebagai
void*
tidak akan memengaruhi apa pun, tetapi begitu itu terjadi, Anda akan macet -__gxx_personality_v0
adalah sebuah fungsi, bukan objek global, jadi cobalah memanggil fungsi tersebut akan melompat ke alamat 0 dan menyebabkan segfault.sumber
Saya mengalami kesalahan ini sekali dan saya menemukan asalnya:
Saya menggunakan kompiler gcc dan file saya dipanggil
CLIENT.C
meskipun saya menggunakan program C dan bukan program C ++.gcc mengenali
.C
ekstensi sebagai program C ++ dan.c
ekstensi sebagai program C (hati-hatilah dengan c kecil dan C besar).Jadi saya mengganti nama
CLIENT.c
program file saya dan itu berhasil.sumber
Jawaban di atas benar: ini digunakan dalam penanganan pengecualian. The pengguna untuk GCC versi 6 memiliki informasi lebih lanjut (yang tidak lagi hadir dalam versi 7 manual). Kesalahan dapat muncul saat menautkan fungsi eksternal yang - tidak diketahui GCC - memunculkan pengecualian Java.
sumber