Формат файла ELF core


Если не копаться в источнике GDB, где я могу найти документацию о формате, используемом для создания основных файлов?

СпецификацияELF оставляет открытым основной формат файла, поэтому я предполагаю, что это должно быть частью спецификаций GDB! К сожалению, я не нашел никакой помощи в этом отношении из документации GNU gdb.

Вот что я пытаюсь сделать: сопоставить виртуальные адреса с именами функций в исполняемых файлах / библиотеках, которые составляли запущенный процесс. Чтобы сделать это, я бы сначала хотелось бы выяснить, из основного файла, карту из виртуального адресного пространства к имени исполняемого файла / библиотеки, а затем копаться в соответствующем файле, чтобы получить символическую информацию.

Теперь 'readelf-A core' говорит мне, что почти все сегменты в файле ядра имеют тип 'load' - я бы предположил, что это .текст и .ОНБ/.сегменты данных из всех участвующих файлов плюс сегмент стека. За исключением этих сегментов нагрузки, есть один сегмент ноты, но это не кажется чтобы содержать карту. Так как же информация о том, какому файлу соответствует сегмент, хранится в файле core? Эти сегменты "загрузки" форматируются определенным образом, чтобы включить информацию о файле?

5 12

5 ответов:

Не столько gdb, сколько библиотека bfd, используемая gdb, binutils, и т.д.

Формат файла дампа ядра использует формат ELF, но не описан в стандарте ELF. АФАИК, нет никаких авторитетных ссылок на это.

Так как же информация о том, какому файлу соответствует сегмент, хранится в файле core?

В примечаниях эльфа содержится много дополнительной информации. Вы можете использовать readelf -n, чтобы увидеть их.

Примечание CORE/NT_FILE определяет связь между диапазоном адресов памяти и файлом (+ смещение):

Page size: 1
             Start                 End         Page Offset
0x0000000000400000  0x000000000049d000  0x0000000000000000
    /usr/bin/xchat
0x000000000069c000  0x00000000006a0000  0x000000000009c000
    /usr/bin/xchat
0x00007f2490885000  0x00007f24908a1000  0x0000000000000000
    /usr/share/icons/gnome/icon-theme.cache
0x00007f24908a1000  0x00007f24908bd000  0x0000000000000000
    /usr/share/icons/gnome/icon-theme.cache
0x00007f24908bd000  0x00007f2490eb0000  0x0000000000000000
    /usr/share/fonts/opentype/ipafont-gothic/ipag.ttf
[...]

Для каждого потока вы должны иметь примечание CORE/NT_PRSTATUS, которое дает вам регистры потока (включая указатель стека). Из этого вы можете сделать вывод о расположении стеков.

Дополнительная информация о формате ELF core файлов:

Дамп ядра - это образ процесса в памяти при его сбое. Он включает в себя сегменты программы, стек, кучу и другие данные. Вам все равно понадобится исходная программа, чтобы понять содержание: таблицы символов и другие данные делают необработанные адреса и структуры в образе памяти значимыми.

Дополнительная информация о процессе, создавшем файл ядра, хранится в разделе ELF note, хотя и в специфическом для операционной системы виде. Например, смотрите страницу руководства core (5) для NetBSD.

Более простым решением вашей проблемы может быть синтаксический анализ текста из /proc/$pid / maps, чтобы определить, к какому файлу сопоставляется данный виртуальный адрес. Затем вы можете проанализировать соответствующий файл.

Открытый исходный код VDB Kenshoto (debugger) использует этот подход, если вы можете читать python, это хороший пример.