2011-01-06 3 views
5

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

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

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

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

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

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

ответ

7

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

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

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

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

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

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

+2

Это весьма вероятно, что проблема - если кадр стека был раздавлен ошибкой, то это пошло. – caf

+0

Upvoted. Если ошибка разбивает стек, тогда нет никакой замены для неудачи рано и громко. assert() - ваш друг. – user47559

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

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

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