Интерпретация сообщений segfault
Какова правильная интерпретация следующих сообщений segfault?
segfault at 10 ip 00007f9bebcca90d sp 00007fffb62705f0 error 4 in libQtWebKit.so.4.5.2[7f9beb83a000+f6f000]
segfault at 10 ip 00007fa44d78890d sp 00007fff43f6b720 error 4 in libQtWebKit.so.4.5.2[7fa44d2f8000+f6f000]
segfault at 11 ip 00007f2b0022acee sp 00007fff368ea610 error 4 in libQtWebKit.so.4.5.2[7f2aff9f7000+f6f000]
segfault at 11 ip 00007f24b21adcee sp 00007fff7379ded0 error 4 in libQtWebKit.so.4.5.2[7f24b197a000+f6f000]
Ответы
Ответ 1
Это segfault из-за следования нулевому указателю, пытающегося найти код для запуска (то есть во время выборки команд).
Если это была программа, а не общая библиотека
Запустите addr2line -e yourSegfaultingProgram 00007f9bebcca90d
(и повторите для других значений указателя инструкции), чтобы увидеть, где происходит ошибка. Лучше, получить сборку отладки и воспроизвести проблему под отладчиком, например gdb.
Поскольку это общая библиотека
Ты хочешь, к сожалению, невозможно узнать, где библиотеки были помещены в память динамическим компоновщиком после факта. Воспроизведите проблему в gdb
.
Что означает ошибка
Здесь разбиение полей:
-
address
(после at
) - местоположение в памяти, к которому пытается обратиться код (вероятно, что 10
и 11
являются смещениями от указателя, который, как мы ожидаем, будет установлен в действительное значение, но который вместо этого указывает на 0
)
-
ip
- указатель инструкции, т.е. где код, который пытается сделать это, живет
-
sp
- указатель стека
-
error
- код ошибки для ошибок страницы; см. ниже, что это означает на x86.
/*
* Page fault error code bits:
*
* 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
*/
Ответ 2
Ошибка 4 означает: "Причина была прочитана в режиме пользователя, в результате чего страница не найдена". Там инструмент, который декодирует его здесь.
Здесь определение из ядра. Имейте в виду, что 4 означает, что бит 2 установлен, и никакие другие биты не установлены. Если вы преобразуете его в двоичный, это станет понятным.
/*
* Page fault error code bits
* bit 0 == 0 means no page found, 1 means protection fault
* bit 1 == 0 means read, 1 means write
* bit 2 == 0 means kernel, 1 means user-mode
* bit 3 == 1 means use of reserved bit detected
* bit 4 == 1 means fault was an instruction fetch
*/
#define PF_PROT (1<<0)
#define PF_WRITE (1<<1)
#define PF_USER (1<<2)
#define PF_RSVD (1<<3)
#define PF_INSTR (1<<4)
Теперь "ip 00007f9bebcca90d" означает, что указатель инструкции находился в 0x00007f9bebcca90d, когда произошел segfault.
"libQtWebKit.so.4.5.2 [7f9beb83a000 + f6f000]" сообщает вам:
- Объект, в котором произошел сбой: "libQtWebKit.so.4.5.2"
- Базовый адрес этого объекта "7f9beb83a000"
- Насколько велик этот объект: "f6f000"
Если вы берете базовый адрес и вычитаете его из ip, вы получаете смещение в этот объект:
0x00007f9bebcca90d - 0x7f9beb83a000 = 0x49090D
Затем вы можете запустить addr2line на нем:
addr2line -e /usr/lib64/qt45/lib/libQtWebKit.so.4.5.2 -fCi 0x49090D
??
??:0
В моем случае это было неудачно, либо установленная мной копия не идентична вашей, либо лишена.
Ответ 3
Перейдите к источнику - 2.6.32, например. Сообщение выводится функцией show_signal_msg() в arch/x86/mm/fault.c, если установлено show_unhandled_signals sysctl.
"ошибка" не является ошибкой или номером сигнала, это "код ошибки ошибки страницы" - см. определение enum x86_pf_error_code.
"[7fa44d2f8000 + f6f000]" - это начальный адрес и размер области виртуальной памяти, в которой объект нарушения был сопоставлен во время сбоя. Значение "ip" должно соответствовать этому региону. С этой информацией в руке вам должно быть легко найти оскорбительный код в gdb.