Как увеличить вероятность совпадения символов ядра дампов Linux? - PullRequest
5 голосов
/ 06 января 2011

У меня очень сложное кроссплатформенное приложение. Недавно мы с моей командой проводили стресс-тесты и столкнулись с несколькими сбоями (и сопровождающими их дампами ядра). Некоторые из этих дампов ядра являются очень точными и показывают точное местоположение, где произошел сбой, с примерно 10 или более кадрами стека. Другие иногда имеют только один кадр стека с быть единственным символом!

То, что я хотел бы знать:

  1. Есть ли способ увеличить вероятность того, что дампы керна будут направлены в правильном направлении?
  2. Почему число фреймов стека не соответствует?
  3. Любые рекомендации по управлению дампами ядра.

Вот как я собираю двоичные файлы (в режиме выпуска):

  1. Компилятор и платформа: g ++ с glibc-2.3.2-95.50 в CentOS 3.6 x86_64 - это помогает мне поддерживать совместимость со старыми версиями Linux.
  2. Все файлы скомпилированы с флагом -g.
  3. Символы отладки извлекаются из окончательного двоичного файла и сохраняются в отдельный файл.
  4. Когда у меня есть дамп ядра, я использую GDB с исполняемым файлом, который создал ядро, и файлом символов. GDB никогда не жалуется на несоответствие между ядром / двоичным символом / символами.

И все же я иногда получаю дампы ядра без символов вообще! Понятно, что я ссылаюсь на не отладочные версии libstdc ++ и libgcc, но было бы неплохо, если бы хотя бы трассировка стека показала мне, откуда в моем коде произошел ошибочный вызов инструкции (хотя в конечном итоге он может закончиться ??) .

Ответы [ 3 ]

7 голосов
/ 06 января 2011

Другие иногда имеют только один кадр стека с "??" быть единственным символом!

Для этого может быть много причин, в том числе:

  • кадр стека был уничтожен (перезаписан)
  • EBP / RBP (на x86 / x64) в настоящее время не имеет никакого значимого значения - это может произойти, например, в единицах, скомпилированных с -fomit-frame-pointer или единицах asm, которые это делают

Обратите внимание, что вторая точка может возникнуть просто, например, путем компиляции glibc таким способом. Наличие отладочной информации для таких системных библиотек может смягчить это (что-то вроде того, что пакеты glibc-debug {info, source} находятся в openSUSE).

GDB имеет больший контроль над программой, чем glibc, поэтому вызов backtrace glibc, естественно, не сможет распечатать обратную трассировку, если GDB не может сделать это тоже.

Но доставка источника будет намного проще: -)

3 голосов
/ 06 января 2011

В качестве альтернативы в системе glibc вы можете использовать вызов функции backtrace (или backtrace_symbols или backtrace_symbols_fd) и отфильтровать результаты самостоятельно, чтобы отображались только символы, принадлежащие вашему собственному коду. Это немного больше работы, но тогда вы действительно можете адаптировать ее к вашим потребностям.

2 голосов
/ 06 января 2011
  1. Вы пытались установить символы отладки различных библиотек, которые вы используете? Например, мой дистрибутив (Ubuntu) предоставляет libc6-dbg, libstdc++6-4.5-dbg, libgcc1-dbg и т. Д.
  2. Если вы строите с включенной оптимизацией (например, -O2), то компилятор может стирать границу между фреймами стека, например, путем встраивания. Я не уверен, что это приведет к обратным трассировкам только с одним кадром стека, но в целом правило состоит в том, чтобы ожидать больших трудностей отладки, поскольку код, который вы просматриваете в дампе ядра, был изменен и поэтому не обязательно соответствует вашему источнику. .
...