Кіріспе

Компьютерлік ақаулық, шектелген жадқа қол жеткізу арқылы туындайды. Есептеу техникасында сегментациялық қателік (көбінесе «сегфолт» деп қысқартылады) немесе жадқа қол жеткізу бұзуы – жадты қорғау механизмі бар аппараттық құралдар тудыратын ақаулық немесе сәтсіздік жағдайы. Бұл операциялық жүйеге (ОЖ) бағдарлама жадтың шектелген бөлігіне қол жеткізуге тырысқанын хабарлайды (жадқа қол жеткізу бұзуы). Стандартты x86 компьютерлерде бұл жалпы қорғаныс қатесінің бір түрі болып табылады. Операциялық жүйе ядросы, әдетте, түзету шараларын қолданады, әдетте, процеске сигнал жіберіп, қате жасаған процеске хабарлайды. Кейбір жағдайларда процестер арнайы сигнал өңдеушіні орнату арқылы өздігінен қателікті жоюға тырыса алады, бірақ көбінесе ОЖ-ның стандартты сигнал өңдеушісі қолданылады, бұл процестің қалыптан тыс тоқтауына (бағдарламаның құлауына) және кейде жадтың резервтік көшірмесін жасауға (core dump) әкеледі. Сегментациялық қателіктер C сияқты, төменгі деңгейдегі жадқа қол жеткізуді қамтамасыз ететін және қауіпсіздік тексеруі аз немесе жоқ тілдерде жазылған бағдарламаларда жиі кездеседі. Олар негізінен виртуалды жад адрестеуінде көрсеткіштерді дұрыс пайдаланбаудан, әсіресе рұқсатсыз қол жеткізуден туындайды. Жадқа қол жеткізу қателерінің тағы бір түрі – шина қатесі, оның да түрлі себептері бар, бірақ қазіргі кезде сирек кездеседі. Олар көбінесе физикалық жад адрестеуінің дұрыс болмауынан немесе жадқа дұрыс емес форматта қол жеткізуден туындайды – аппараттық құралдардың адрестей алмайтын жад сілтемелері, процеске рұқсат етілмеген сілтемелерге қарағанда. Көптеген бағдарламалау тілдері сегментациялық қателіктерді болдырмау және жад қауіпсіздігін арттыру үшін арнайы механизмдерді ұсынады. Мысалы, Rust жад қауіпсіздігін қамтамасыз ету үшін меншікке негізделген модельді қолданады. Lisp және Java сияқты басқа тілдер қоқыс жинауды (garbage collection) пайдаланады, бұл сегментациялық қателіктерге әкелуі мүмкін жад қателерінің белгілі бір түрлерін болдырмайды.

Шолу

Сегменттеу қатесі бағдарламаға рұқсат етілмеген жад орнына қол жеткізуге тырысқанда немесе жад орнына рұқсат етілмеген тәсілмен қол жеткізуге тырысқанда (мысалы, тек оқуға арналған жерге жазуға тырысқанда немесе операциялық жүйенің бөлігін жаза бергенде) пайда болады. "Сегментация" термині компьютерлік техникада әртүрлі мағыналарда қолданылады; "сегментация қатесі" контекстінде ол бағдарламаның адрестік кеңістігін білдіреді. Жадының қорғалуы арқасында бағдарламаның өзінің адрестік кеңістігі ғана оқыла алады, ал осының ішінде тек стек пен деректер сегментінің оқу/жазу бөлігі ғана жазыла алады, ал const сегменті мен код сегментіндегі деректерді жазуға болмайды. Сондықтан бағдарламаның адрестік кеңістігінен тыс жерді оқуға тырысу немесе адрестік кеңістіктің тек оқуға арналған сегментіне жазу сегменттеу қатесіне алып келеді, сондықтан осылай аталады. Виртуалды жадты қамтамасыз ету үшін аппараттық жад сегментациясын пайдаланатын жүйелерде, аппараттық құралдар жоқ сегментке, сегмент шегінен тыс жерге немесе осы сегментке берілген рұқсаттармен үйлеспейтін тәсілмен сілтеме жасау әрекетін анықтағанда сегментация қатесі пайда болады. Тек беттеуді қолданатын жүйелерде жарамсыз бет қатесі көбінесе сегментация қатесіне әкеледі, ал сегментация қатесі мен бет қатесі – екеуі де виртуалды жадты басқару жүйесінің тудырған қателері. Сегментация қателері бет қателеріне тәуелсіз де болуы мүмкін: жарамды бетке заңсыз қол жеткізу – сегментация қатесі, бірақ жарамсыз бет қатесі емес, және сегментация қателері беттің ішінде (сондықтан бет қатесі болмайды) пайда болуы мүмкін, мысалы, беттің ішінде қалатын, бірақ жадты заңсыз жазатын буфер асығуында. Аппараттық деңгейде, қате бастапқыда жад басқару бірлігі (MMU) заңсыз қол жеткізу кезінде (егер сілтемелі жад болса), оның жадты қорғау мүмкіндігінің бөлігі ретінде немесе жарамсыз бет қатесі (егер сілтемелі жад болмаса) кезінде туындайды. Егер мәселе жарамсыз логикалық адрес емес, жарамсыз физикалық адрес болса, автобус қатесі туындайды, бірақ олар әрқашан ажыратылмайды. Операциялық жүйе деңгейінде бұл қате анықталады және сигнал зардап шеккен процеске жіберіледі, бұл сигналға процестің өңдеушісі іске қосылады. Әртүрлі операциялық жүйелерде сегментация қатесі болғанын көрсету үшін әртүрлі сигнал атаулары бар. Unix сияқты операциялық жүйелерде SIGSEGV (сегментация бұзуынан қысқартылған) деп аталатын сигнал зардап шеккен процеске жіберіледі. Microsoft Windows жүйесінде зардап шеккен процесс STATUS ACCESS VIOLATION ерекшелігін алады.

Қолдану

Сегменттеу қатесі немесе шина қатесі үшін стандартты әрекет – оны тудырған процестің қалыптан тыс тоқтатылуы болып табылады. Жарамсауды жеңілдету үшін ядро файлы жасалуы мүмкін, сондай-ақ платформаға тәуелді басқа да әрекеттер орындалуы мүмкін. Мысалы, grsecurity патчы қолданылған Linux жүйелері буфер асығуын пайдаланып, әлеуетті бұзу әрекеттерін бақылау үшін SIGSEGV сигналдарын тіркеуі мүмкін. Linux және Windows сияқты кейбір жүйелерде бағдарламаның өзі сегменттеу қатесін өңдеуі мүмкін. Архитектура мен операциялық жүйеге байланысты, жұмыс істеп жатқан бағдарлама тек оқиғаны өңдеп қана қоймай, оның күйі туралы ақпаратты да алуы мүмкін, мысалы, стек ізбесін, процессор тіркелгіштерінің мәндерін, қате тудырған кодтың жолын, жарамсыз қол жеткізілген жад адресін және осы әрекет оқу немесе жазу болғандығын анықтауға болады. Сегменттеу қатесі көбінесе бағдарламада түзетуді қажет ететін қате бар екенін көрсетеді, бірақ сынақтар жүргізу, қателерді жою және жадқа тікелей қол жеткізуді қажет ететін платформаларды модельдеу мақсатында осы қателерді әдейі тудыруға да болады. Соңғы жағдайда, жүйе қате пайда болғаннан кейін де бағдарламаның жұмысын жалғастыруға мүмкіндік беруі керек. Мұндай жағдайда, жүйе рұқсат берсе, оқиғаны өңдеп, процессор бағдарламасының санағышын қателі инструкциядан өту үшін арттыруға болады, осылайша орындалу жалғасады.