Удаленный анализ дампа памяти после смерти без точных символов отладки для общих системных библиотек

Как вы обычно решаете эту проблему? Представьте, что происходит сбой потока внутри кода libc (который является системной общей библиотекой) на компьютере Computer1, а затем создается дамп памяти. Но компьютер2, на котором будет анализироваться этот дамп памяти, может иметь другую версию libc.

So:

  1. Насколько важно иметь одну и ту же общую библиотеку на удаленном компьютере? Будет ли gdb правильно реконструировать трассировку стека, если на Conputer2 не будет точно такой же версии libc?

  2. Насколько важно иметь правильные символы отладки для libc? Будет ли gdb правильно реконструировать трассировку стека, не имея точно таких же символов отладки на Computer2?

  3. И каков «правильный» способ избежать этой проблемы несоответствия символов отладки для общих системных библиотек? Мне кажется, что нет единого решения, которое элегантно решает эту проблему? Может кто поделится своим опытом?


person user389238    schedule 01.12.2010    source источник


Ответы (1)


  1. Это зависит. На некоторых процессорах, таких как x86_64, требуются правильные дескрипторы очистки. чтобы GDB правильно разматывал стек. На такой машине анализ дампа памяти с несоответствующей libc, скорее всего, приведет к полному мусору.

  2. Вам не нужны символы отладки для libc, чтобы получить трассировку стека. Вы не получите номера файлов и строк без символов отладки, но вы должны получить правильные имена функций (за исключением случаев, когда имело место встраивание).

  3. Предпосылка вашего вопроса неверна - символы отладки не имеют к этому никакого отношения. «Правильный» способ анализа дампа памяти на C2, когда этот дамп памяти был создан на C1, состоит в том, чтобы иметь копию библиотек C1 (например, /tmp/C1/lib/...) и указать GDB использовать эту копию вместо установленной на C2 libc с

    (gdb) set solib-absolute-prefix /tmp/C1

команда.

Примечание: приведенная выше настройка должна действовать до того, как вы загрузите ядро ​​в GDB. Этот:

gdb exe core
(gdb) set solib-absolute-prefix /tmp/C1

не будет работать (ядро читается до того, как настройка вступит в силу).

Вот правильный путь:

gdb exe
(gdb) set solib-absolute-prefix /tmp/C1
(gdb) core core

(Я пытался найти ссылку на это в Интернете, но не нашел).

Что такое дескрипторы раскрутки?

Дескрипторы очистки требуются, когда код компилируется без указателей кадров (по умолчанию для x86_64 в оптимизированном режиме). Такой код не сохраняет регистр %rbp, поэтому GDB необходимо сообщить, как "отступить" от текущего кадра к вызывающему кадру (этот процесс также известен как раскручивание стека).

Почему libc.so C1 не включена в ядро?

Основной файл обычно содержит только содержимое доступных для записи сегментов адресного пространства программы. Сегменты только для чтения (где находится исполняемый код и дескрипторы раскрутки) обычно не нужны — вы можете просто прочитать их непосредственно из libc.so на диске.

За исключением того, что это не работает, когда вы анализируете ядро ​​​​C1 на C2!

Некоторые (но не все) операционные системы позволяют настраивать «полные дампы ядра», когда ОС также будет создавать дамп сопоставлений только для чтения, именно поэтому вы можете анализировать ядро ​​​​на любой машине.

person Employed Russian    schedule 03.12.2010
comment
1. Не могли бы вы объяснить термин «правильные дескрипторы раскрутки» - вы имеете в виду регистры SP и BP, которые были помещены в стек? 2. Когда создается coredump, все разделяемые библиотеки также включаются в coredump, потому что это в основном дамп памяти? Так почему же GDB должен иметь файл libc.so, хотя он может использовать libc из coredump? - person user389238; 03.12.2010
comment
Я ответил на ваши дополнительные вопросы (как мог). - person Employed Russian; 03.12.2010
comment
Спасибо - ответы отличные! Мне все еще любопытно, где найти дополнительную информацию о том, как работают дескрипторы раскрутки... - person user389238; 03.12.2010