Улучшение отладки при сбое Linux в программе на C - PullRequest
7 голосов
/ 24 ноября 2011

У нас есть встроенная версия ядра Linux, работающая на ядре MIP. Программа, которую мы написали, запускает определенный набор тестов. Во время одного из стресс-тестов (продолжительностью около 12 часов) мы получаем ошибку сегмента. Это, в свою очередь, создает дамп ядра.

К сожалению, дамп ядра не очень полезен. Сбой происходит в какой-то системной библиотеке, которая динамически связана (возможно, pthread или glibc). Обратная трассировка в дампе ядра не полезна, потому что она показывает только точку сбоя и никаких других вызывающих абонентов (наше приложение пользовательского пространства построено с -g -O0, но по-прежнему нет информации обратной трассировки):

Cannot access memory at address 0x2aab1004
(gdb) bt
#0  0x2ab05d18 in ?? ()
warning: GDB can't find the start of the function at 0x2ab05d18.

    GDB is unable to find the start of the function at 0x2ab05d18
and thus can't determine the size of that function's stack frame.
This means that GDB may be unable to access that stack frame, or
the frames below it.
    This problem is most likely caused by an invalid program counter or
stack pointer.
    However, if you think GDB should simply search farther back
from 0x2ab05d18 for code which looks like the beginning of a
function, you can increase the range of the search using the `set
heuristic-fence-post' command.

Еще одна неприятность заключается в том, что мы не можем запустить gdb / gdbserver. GDB / GDBserver продолжает работать на __nptl_create_event. Видя, что тест создает потоки, таймеры и уничтожает их, каждые 5 секунд практически невозможно долго сидеть, продолжая их.

EDIT: Еще одно замечание, backtrace и backtrace_symbols не поддерживаются в нашей цепочке инструментов.

Таким образом:

  1. Есть ли способ перехвата ошибки сегмента и генерирования большего количества данных обратной трассировки, указателей стека, стека вызовов и т. Д .?

  2. Есть ли способ получить больше данных из дампа ядра, который упал в файле .so?

Спасибо.

Ответы [ 2 ]

1 голос
/ 24 ноября 2011

GDB не может найти начало функции в 0x2ab05d18

Что находится по этому адресу во время аварии?

Выполните info shared и выясните, есть ли библиотека, содержащая этот адрес.

Наиболее вероятная причина ваших проблем: вы запустили strip libpthread.so.0 перед загрузкой в ​​свою цель? Не делайте этого: GDB требует от libpthread.so.0 до , а не . Если ваш набор инструментов содержит libpthread.so.0 с символами отладки (и, следовательно, слишком велик для цели), запустите на нем strip -g, а не полный strip.

Обновление:

info shared произведено Не удается получить доступ к памяти по адресу 0x2ab05d18

Это означает, что GDB не может получить доступ к списку совместно используемых библиотек (что затем объясняет отсутствующую трассировку стека). Самая обычная причина: двоичный файл, который фактически произвел core, не соответствует двоичному файлу, который вы дали GDB. Менее распространенная причина: ваш дамп ядра был усечен (возможно, из-за слишком низкого значения ulimit -c).

1 голос
/ 24 ноября 2011

Если ничего не помогает, запустите команду с помощью отладчика!

Просто введите "gdb" в форме вашей обычной команды запуска и введите "c", чтобы запустить процесс. Когда задача потерпит неудачу, она вернется к интерактивной подсказке gdb, а не к дампу ядра. После этого вы сможете получить более значимые следы стека и т. Д.

Другой вариант - использовать «ферму», если она доступна. Это скажет вам, какие системные вызовы использовались во время завершения.

...