Skip to content

Сервер: расследование крашей

Ruffina Koza edited this page Sep 21, 2018 · 3 revisions

Как заставить core dump сохраняться на диск в случае краша (SEGFAULT)

Скрипт autorun, ответственный за перезапуск сервера после ребутов и крашей, явно устанавливает размер файла корки в "неограниченный", командой ulimit -c unlimited. Файлы корок будут сохранены в каталог runtime в формате core.timestamp, сохраняется только 3 последние корки.

Как анализировать coredump

Запуск дебаггера:

$ cd /home/planescape/runtime
$ gdb ./bin/planescape core
...
Program terminated with signal SIGSEGV, Segmentation fault.
#0  do_noplayer (ch=0xcbfe8b0, argument=0xffea4da4 "", cmd=266, subcmd=0, countcmd=1) at ../../../planescape_code/plug-ins/runtime/act.wizard.cpp:61

Показать stack trace, приведший к крашу:

(gdb) bt
#0  do_noplayer (ch=0xcbfe8b0, argument=0xffea4da4 "", cmd=266, subcmd=0, countcmd=1) at ../../../planescape_code/plug-ins/runtime/act.wizard.cpp:61
#1  0xf6cbfcaa in command_interpreter (ch=0xcbfe8b0, cargument=0xffea6dfc "noplayer") at ../../../planescape_code/plug-ins/runtime/interpreter.cpp:446
#2  0xf6d4d17a in IOManager::ioRead (this=0x9a03918) at ../../../planescape_code/plug-ins/runtime/iomanager.cpp:210
#3  0xf6d4d1ec in IOReadTask::run (this=0x9a03d60) at ../../../planescape_code/plug-ins/runtime/iomanager.cpp:63

Показать stack trace со всеми значениями локальных переменных (если не оптимизированы):

(gdb) bt full

Перемещение по stack frames вверх и вниз:

(gdb) up
(gdb) down

Просмотр содержимого переменных: установите текущий frame и воспользуйтесь командой p (print). Можно также настроить более приятный глазу режим вывода.

(gdb) down
#0  do_noplayer (ch=0xcbfe8b0, argument=0xffea4da4 "", cmd=266, subcmd=0, countcmd=1) at ../../../planescape_code/plug-ins/runtime/act.wizard.cpp:61
(gdb) set print pretty
(gdb) p *ch
$6 = {
  <WrapperTarget> = {
    wrapper = 0x998e158
  }, 
  members of char_data: 
...

Как найти место краша в отсутствие корки

Если корка по каким-то причинам не сохранилась, все равно можно найти строку в исходниках, где произошел краш, если конечно исходники с тех пор не менялись. Для этого воспользуемся выводом команды dmesg в "человеческом" формате:

$ dmesg -H
[Sep20 23:09] planescape[8414]: segfault at 530 ip 00000000f6c985f6 sp 00000000ffc579e0 error 4 in libruntime.so.0.0.0[f6afd000+266000]
  • error 4 означает "user-mode read resulting in no page being found."
  • libruntime.so.0.0.0 - либа где произошел сбой
  • 0xf6afd000 - ее базовый адрес
  • 0x266000 - ее размер
  • ip 00000000f6c985f6: положение instruction pointer в момент краша

Вычтя базовый адрес из ip, получим адрес смещения внутри либы, где произошел сбой. Для вычислений можно воспользоваться gdb как калькулятором:

(gdb) p/x 0x00000000f6c985f6 - 0xf6afd000
0x19b5f6

Потом с помощью утилиты addr2line выведем строку исходников, соответствующих данному адресу:

$ addr2line  -e libexec/plugins/libruntime.so.0.0.0 -fCia 0x19b5f6
0x0019b5f6
get_save_obj(obj_data*, int)
/home/planescape/objs/plug-ins/runtime/../../../planescape_code/plug-ins/runtime/utils.cpp:2902

$ vi /home/planescape/objs/plug-ins/runtime/../../../planescape_code/plug-ins/runtime/utils.cpp +2902