2014-11-25 1 views
0

Я следовал инструкциям несколько аналогичного SO question, но строка, которую я получаю, не имеет смысла.сбой расширения php - преобразование адреса памяти в номер строки

У меня есть процесс apache, выполняющий php, скомпилированный с помощью специального расширения c php. Иногда я получаю ошибку сегментации и дамп ядра.

Это работает на обновленном сервере RHEL 6.5.

Я установил debuginfo rpm для нашего расширения php. Открытие ядра и получение Бритиш дает мне

(gdb) bt 
#0 0x00007f7d7b99dd2f in ??() from /etc/httpd/modules/libphp5.so 
#1 0x00007f7d74783c81 in zif_x12_parse_file() from /usr/lib64/php/modules/x12_parser.so 
#2 0x00007f7d7ba093b8 in ??() from /etc/httpd/modules/libphp5.so 
#3 0x00007f7d7b9e0500 in execute() from /etc/httpd/modules/libphp5.so 
#4 0x00007f7d7b9ba70d in zend_execute_scripts() from /etc/httpd/modules/libphp5.so 
#5 0x00007f7d7b968798 in php_execute_script() from /etc/httpd/modules/libphp5.so 
#6 0x00007f7d7ba43d75 in ??() from /etc/httpd/modules/libphp5.so 
#7 0x00007f7d864b4bb0 in ap_run_handler() 
#8 0x00007f7d864b846e in ap_invoke_handler() 
#9 0x00007f7d864c3b30 in ap_process_request() 
#10 0x00007f7d864c09a8 in ??() 
#11 0x00007f7d864bc6b8 in ap_run_process_connection() 
#12 0x00007f7d864c8977 in ??() 
#13 0x00007f7d864c8c8a in ??() 
#14 0x00007f7d864c8fbb in ap_mpm_run() 
#15 0x00007f7d864a0900 in main() 

Я предполагаю, что проблема на самом деле в нашем коде, а не PHP в верхней части стека. Таким образом, я получаю местоположение так загружен

(gdb) info shared x12 
From    To     Syms Read Shared Object Library 
0x00007f7d7477ec20 0x00007f7d74784038 Yes   /usr/lib64/php/modules/x12_parser.so 

Вычитания начального местоположения нагрузки от места

0x00007f7d74783c81 − 0x00007f7d7477ec20 = 5061 

стек памяти и штамповок, что в addr2line

$ addr2line -e /usr/lib/debug/usr/lib64/php/modules/x12_parser.so.debug 0x5061 
/usr/src/debug/php-x12_parser-5.3.3/php-x12_parser/x12_parser.c:321 

Но, линия 321 ISN 't в файле zif_x12_parse_file. И даже если бы это было так, это не та линия, которая, как я предполагаю, может потерпеть крах.

Так что же я сделал неправильно при расчете линии аварии?

ответ

0

Оказалось, что я делал так, чтобы усердно. Мне просто нужно было установить debuginfo rpm перед сбоем. Теперь я получаю хорошие следы назад.

#0 0x00007fc97334fd2f in ??() from /etc/httpd/modules/libphp5.so 
#1 0x00007fc96c135b3b in zif_x12_parse_file (ht=<value optimized out>,return_value=0x7fc98ec278f8, return_value_ptr=<value optimized out>, this_ptr=<value optimized out>, return_value_used=<value optimized out>) at /usr/src/debug/php-x12_parser-5.3.3/php-x12_parser/x12_parser.c:609 
#2 0x00007fc9733bb3b8 in ??() from /etc/httpd/modules/libphp5.so 
#3 0x00007fc973392500 in execute() from /etc/httpd/modules/libphp5.so 
0
  • перекомпилировать библиотеку с -gdb3.
  • затем запустите программу (по-видимому через gdb)
  • Посмотрите на трассировку стека.

Примечание: эти линии имеют? из файлов, которые были скомпилированы без все данные gdb

+0

Он уже был скомпилирован с -g, который является общей версией -gdb. -gdb3 возвращает уровень отладочной информации, которая была доступна, но не решила бы проблему, которую я видел. –

0

Вместо того чтобы использовать базовый адрес из info sharedlibrary команды gdb «s, используйте базовый адрес с карты памяти текущего процесса, /proc/#####/maps.

gdb будет следить за самой низкой доступный адрес для исполняемого адресного пространства совместно используемой библиотеки, как правило, принимает p_vaddr запись в .text секции файла ELF и перемещение его на основании отображенной области.

Вот пример:

#include <stdlib.h> 

main() 
{ 
    char arg[40]; 
    sprintf(arg, "grep libc /proc/%d/maps", getpid()); 
    system(arg); 
    abort(); 
} 
 
$ gdb ab 
(gdb) run 
7ffff7a14000-7ffff7bcf000 r-xp 00000000 08:01 397695 /lib/x86_64-linux-gnu/libc-2.19.so 
7ffff7bcf000-7ffff7dcf000 ---p 001bb000 08:01 397695 /lib/x86_64-linux-gnu/libc-2.19.so 
7ffff7dcf000-7ffff7dd3000 r--p 001bb000 08:01 397695 /lib/x86_64-linux-gnu/libc-2.19.so 
7ffff7dd3000-7ffff7dd5000 rw-p 001bf000 08:01 397695 /lib/x86_64-linux-gnu/libc-2.19.so 
Program received signal SIGABRT, Aborted. 
0x00007ffff7a4abb9 in __GI_raise ([email protected]=6) at 
         ../nptl/sysdeps/unix/sysv/linux/raise.c:56 
(gdb) info sharedlibrary 
From    To     Syms Read Shared Object Library 
0x00007ffff7ddaae0 0x00007ffff7df54e0 Yes  /lib64/ld-linux-x86-64.so.2 
0x00007ffff7a334a0 0x00007ffff7b790c3 Yes  /lib/x86_64-linux-gnu/libc.so.6 

$ eu-readelf -S /lib/x86_64-linux-gnu/libc-2.19.so | egrep 'Name|text' 
[Nr] Name  Type   Addr    Off  Size  ES Flags Lk Inf Al 
[12] .text  PROGBITS  000000000001f4a0 0001f4a0 00145c23 0 AX  0 0 16 

$ printf "%x\n" $((0x7ffff7a14000 + 0x1f4a0)) 
7ffff7a334a0 

Дайте addr2line разницу между желаемым адресом команды и основания отображенной области:

 
$ printf "%x\n" $((0x00007ffff7a4abb9 - 0x7FFFF7A14000)) 
36bb9 
$ addr2line -e /lib/x86_64-linux-gnu/libc-2.19.so 36bb9 
/build/buildd/eglibc-2.19/signal/../nptl/sysdeps/unix/sysv/linux/raise.c:56 

Имейте в виду, что указатель инструкция вероятно, указывая на инструкцию после той, которая вызвала ошибку, поэтому в некоторых случаях (но не в этот пример) номер строки источника может быть отключен на 1.

 Смежные вопросы

  • Нет связанных вопросов^_^