Подтвердить что ты не робот

Интерпретация сообщений 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]
4b9b3361

Ответ 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.