2014-11-12 1 views
0

Я хотел бы извлечь стек из трещащих приложений с большими отпечатками памяти. В идеале пользователю не нужно ждать, пока весь файл coredump будет записан на диск.Является ли исполняемый и связанный формат (ELF) доступным?

Мое настоящее мышление заключается в установке крюка coredump на /proc/sys/kernel/core_pattern, который будет анализировать входящий coredump через stdin и извлекать только стек. Но создание полной копии coredump в памяти было бы непрактичным, поэтому потоковый подход был бы лучше.

Я новичок в формате ELF (http://en.wikipedia.org/wiki/Executable_and_Linkable_Format) и задавался вопросом, может ли он поддерживать потоковый синтаксический анализатор. Я еще не написал потоковый анализатор любого типа - я знаком с концепцией, но мне нужны указатели на то, как анализировать формат потоков.

В качестве первой попытки, я попробовал:

cat core | readelf -a 

Но, это не похоже, readelf поддерживает ввод из стандартного ввода.

Я также нашел этот питон эльфа парсер, но это кажется на первый взгляд, как он читает весь эльфа в память: https://github.com/eliben/pyelftools

Но, в случае необходимости, может быть, я мог бы использовать их реализацию в качестве ссылки для потокового парсера ,

Спасибо!

ответ

0

Оказывается, что coredumper Google документирует формат основной файл ELF: https://code.google.com/p/google-coredumper/source/browse/trunk/src/elfcore.c

Этот фрагмент кода был также полезен: http://emntech.blogspot.com/2012/08/printing-backtracestack-trace-using.html

Оказывается, что StackTrace содержится в одном сегменте эльфа , Затем раствор должен:

  1. Прочитайте эльфа заголовки
  2. Найти запись нотного типа NT_PRSTATUS
  3. Получить верх адреса стека из регистра в данной записи
  4. Перейти к этому адресу
  5. Читать StackTrace
  6. Игнорируйте остальные CoreDump

I все еще есть некоторая работа, чтобы сделать с точки зрения разрешения символов и т. д. Но, я отредактирую этот ответ, если мой подход значительно изменится. Хотя вопрос о том, может ли формат быть «потоковым», на самом деле не был правильным вопросом, я нашел решение, которое позволило мне прочитать stacktrace без написания всего файла coredump на диске.

EDIT:

Согласно ответам на How gdb reconstructs stacktrace for C++?, кажется, что реконструкция стека во всех случаях является довольно сложным. Я считаю, что окончательный ответ на этот вопрос: нет, невозможно извлечь стек из ядер ELF, а ядро ​​ELF не является «плавным».

Я считаю, что, хотя есть вероятность, что куча может быть расположена в коробчатой ​​шахте и удалена. Это оставило бы стек неповрежденным, позволяя gdb еще восстановить его.

+1

Обратите внимание, что найденное решение backtrace будет работать только для 32-разрядных двоичных файлов, а только для тех, которые были скомпилированы без оптимизации, или со старыми версиями GCC. –

+0

@EmployedRussian - можете ли вы предоставить более подробную информацию о том, почему это не будет работать для 64-битного? – matthewatabet

+1

@matthewtablet код backtracestack использует указатели на фреймы, которые по умолчанию отключены на 'x86_64' с оптимизацией. Используя новые версии GCC, указатели на рамки также отключены с оптимизацией на 'ix86' (32-разрядной). Разматывание без указателей рамки намного сложнее; вам нужно что-то вроде libunwind. –

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