Kerosakan pensegmenan
Kerosakan pensegmenan (dalam bahasa Inggeris segmentation fault, disingkatkan kepada segfault) atau cabul capaian (dalam bahasa Inggeris access violation) ialah ralat bagi sesebuah perisian komputer yang terjadi apabila ia cuba untuk mencapai tempat ingatan yang tidak dibenarkan untuk dicapai, atau cuba untuk mencapai tempat ingatan dengan cara yang tidak dibenarkan (contohnya, cubaan untuk menulis pada tempat baca sahaja, atau cubaan untuk menulis-ganti sebahagian sistem pengendalian).
Pensegmenan ialah satu langkah pengurusan ingatan dan perlindungan dalam sistem pengendalian. Walaupun kebanyakan tujuannya telah digantikan oleh penghalaman, namun masih banyak istilah pensegmenan digunakan, "kerosakan pensegmenan" adalah satu contoh. Sesetengah sistem pengendalian masih memiliki pensegmenan pada suatu tahap logik walaupun penghalaman digunakan sebagai polisi pengurusan ingatan utama.
Dalam sistem penggendalian ala Unix, isyarat yang digelar SIGSEGV dihantar kepada proses yang sedang mencapai alamat ingatan yang tidak sah. Pada Microsoft Windows, sebuah proses yang mencapai ingatan tak sah menerima pengecualian STATUS_ACCESS_VIOLATION.
Contoh
suntingBerikut merupakan contoh kod ANSI C yang sepatutnya menghasilkan kerosakan pensegmenan pada pelantar yang memiliki perlindungan ingatan:
int main(void)
{
char *s = "indahnya dunia";
*s = 'H';
}
Apabila atur cara yang mengandungi kod ini dikompilkan, rentetan "indahnya dunia" diletakkan di dalam seksyen perduaan atur cara terbabit yang ditandakan sebagai baca sahaja; bila dimuat, sistem pengendalian meletakkanya bersama rentetan-rentetan lain dan data pemalar dalam segmen baca-sahaja ingatan. Apabila dilakukan, pemboleh ubah s disetkan untuk menuding kepada tempat rentetan berkenaan, dan satu cubaan dilakukan untuk menulis aksara H melalui pemboleh ubah itu kepada ingatan, lantas menyebabkan kerosakan pensegmenan. Mengkompil atur cara sebegini dengan pengkompil yang tidak memeriksa penugasan ingatan baca-sahaja semasa pengkompilan, dan menjalankannya pada sistem pengendalian ala Unix akan menghasilkan ralat masa jalanan berikut:
$ gcc segfault.c -g -o segfault
$ ./segfault
Segmentation fault
Pengesanan balik daripada gdb:
Program received signal SIGSEGV, Segmentation fault.
0x1c0005c2 in main () at segfault.c:6
6 *s = 'H';
Keadaan-keadaan di mana pencabulan pensegmenan berlaku dan bagaimana mereka menunjukkan diri adalah khusus mengikut sistem pengendalian.
Kerana ralat atur-cara yang paling biasa adalah suatu penyahrujukan penuding nol (baca atau tulis menerusi penuding nol, digunakan dalam C untuk membawa maksud "penuding kepada tiada objek" dan sebagai penunjuk ralat), kebanyakan sistem pengendalian memetakan alamat penuding nol supaya mencapainya akan menyebabkan kerosakan pensegmenan.
int *ptr = NULL;
*ptr = 1;
Contoh kod ini mencipta sebuah penuding nol dan cuba untuk menugaskan satu nilai kepada sasarannya yang tidak wujud. Ini menyebabkan kerosakan pensegmenan pada masa jalan pada kebanyakan sistem pengendalian.
Satu lagi cara untuk menghasilkan kerosakan pensegmenan ialah dengan mengulang tanpa kes asas, yang menyebabkan limpah atas tindanan:
int main(void)
{
main();
}