Thank you for reading this post, don't forget to subscribe!
Ошибка сегментации (в оригинале segmentation fault часто сокращаемая до segfault) или нарушение доступа — это ошибка, возникшая у оборудования с защитой памяти, чтобы уведомить операционную систему (ОС) о нарушении доступа к памяти.
Ядро Linux отвечает на него, выполняя некоторые корректирующие действия, обычно передавая ошибку в процесс-нарушитель, посылая процессу сигнал типа # 11.
В некоторых случаях процессы могут устанавливать пользовательский обработчик сигналов, что позволяет им восстанавливаться самостоятельно, но в противном случае используется обработчик сигналов по умолчанию в Linux.
Обычно segfault приводит к завершению процесса и генерирует дамп ядра с правильной настройкой ulimit.
Как проверить?
1. Определить segfault
Segfault обычно просто означает ошибку в одном конкретном процессе или программе.
Это не означает ошибку ядра Linux.
Ядро просто обнаруживает ошибку процесса или программы и (на некоторых архитектурах) выводит информацию в журнал, как показано ниже:
1 2 3 |
kernel: login[118125]: segfault at 0 ip 00007f4e4d5334a8 sp 00007fffe9177d60 error 15 in pam_unity_uac.so[7f4e4d530000+b000] kernel: crond[16398]: segfault at 14 ip 00007fd612c128f2 sp 00007fff6a689010 error 4 in pam_seos.so[7fd612baf000+f5000] kernel: crond[17719]: segfault at 14 ip 00007fd612c128f2 sp 00007fff6a689010 error 4 in pam_seos.so[7fd612baf000+f5000 |
2. Что означает подробности этого сообщения?
Значение RIP — это значение регистра указателя команды, а RSP — значение регистра указателя стека.
Значением ошибки является битовая маска битов кода ошибки страницы (из arch/x86/mm/fault.c):
1 2 3 4 5 |
* bit 0 == 0: no page found 1: protection fault * bit 1 == 0: read access 1: write access * bit 2 == 0: kernel-mode access 1: user-mode access * bit 3 == 1: use of reserved bit detected * bit 4 == 1: fault was an instruction fetch |
Вот определение бита ошибки:
1 2 3 4 5 6 7 |
enum x86_pf_error_code { PF_PROT = 1 << 0, PF_WRITE = 1 << 1, PF_USER = 1 << 2, PF_RSVD = 1 << 3, PF_INSTR = 1 << 4, }; |
Код ошибки 15 — 1111 бит.
Наконец, мы можем узнать значение 1111 следующим образом:
1 2 3 4 5 6 7 |
01111 ^^^^^ ||||+---> bit 0 |||+----> bit 1 ||+-----> bit 2 |+------> bit 3 +-------> bit 4 |
Это сообщение указывает, что приложение вызывает ошибку защиты, потому что этот процесс пытался записать доступ к зарезервированному разделу памяти в режиме пользователя.