Когда я компилирую программу с -g и получаю дамп ядра, я могу использовать gdb
чтобы прочитать исполняемый файл и дамп ядра, чтобы отладить ситуацию, в которой запустилась программа до ее сбоя. Одна из особенностей gdb
предложения это list
опцию, можно перечислить исходный код, который был скомпилирован с использованием исполняемого файла и дампа ядра. я использовал strings -a
с исполняемым файлом и дампом ядра, и я не смог найти ни одного if
или же for
заявления, пока я уверен, что в коде их много. Так откуда берется код? Я компилирую код на одном компьютере и запускаю его на другом, чтобы исходный код не был доступен на компьютере, где создается дамп ядра, и, похоже, он не находится внутри исполняемого файла или дампа ядра. Какие-либо предложения? Я действительно хочу напечатать весь исходный код из исполняемого файла и из дампа ядра, это возможно? Я имею в виду без бега gdb
Я уверен, что можно написать сценарий, который использует GDB и может перечислить весь код, но я заинтересован в том, чтобы сделать это самостоятельно без gdb
потому что я хочу понять, откуда взят исходный код, как он отформатирован, я хочу узнать как можно больше об этом.
Информация о линии находится в .debug_line
DWARF-разделы исполняемого файла:
$readelf -wL ./a.out
Decoded dump of debug contents of section .debug_line:
CU: bla.c:
File name Line number Starting address
bla.c 2 0x4004b6
bla.c 3 0x4004ba
bla.c 4 0x4004bf
Этот раздел отображает адреса указателей команд на номера строк в данном файле.
Чтобы найти содержимое файла, вы должны быть в состоянии найти соответствующий исходный файл. Если вы переместите / переименуете исходный файл, GDB не сможет распечатать исходный код:
mv bla.c bla2.c GDB ./a.out (GDB) сломать основной (GDB) запустить (GDB) список 1 в бла
.debug_info
Разделы DWARF содержат некоторую информацию о пути к исходному файлу, когда он был скомпилирован, который может быть использован для поиска соответствующего файла:
$ objdump -Wi -wa ./a.out ./a.out: формат файла elf64-x86-64 ./a.out Содержимое раздела .debug_info: Блок компиляции @ смещение 0x0: Длина: 0x4e (32-разрядная) Версия: 4 Abbrev Offset: 0x0 Размер указателя: 8 : Сокращенный номер: 1 (DW_TAG_compile_unit) DW_AT_producer: (косвенная строка, смещение: 0x0): GNU C 4.9.1 -mtune = универсальный -march = x86-64 -g DW_AT_language: 1 (ANSI C) DW_AT_name: (косвенная строка, смещение: 0x59): bla.c DW_AT_comp_dir: (непрямая строка, смещение: 0x31): / home / себя / temp / bla DW_AT_low_pc: 0x4004b6 DW_AT_high_pc: 0xb DW_AT_stmt_list: 0x0 : Сокращенный номер: 2 (DW_TAG_subprogram) DW_AT_external: 1 DW_AT_name: (косвенная строка, смещение: 0x2c): основной DW_AT_decl_file: 1 DW_AT_decl_line: 2 DW_AT_type: DW_AT_low_pc: 0x4004b6 DW_AT_high_pc: 0xb DW_AT_frame_base: 1-байтовый блок: 9c (DW_OP_call_frame_cfa) DW_AT_GNU_all_call_sites: 1 : Сокращенный номер: 3 (DW_TAG_base_type) DW_AT_byte_size: 4 DW_AT_encoding: 5 (подписано) DW_AT_name: int : Аббревиатура номер: 0
каждый DW_TAG_compile_unit
содержит информацию об имени исходного файла и пути к нему, который используется для поиска соответствующего исходного файла.
Если вы хотите сделать все самостоятельно, вам, вероятно, следует прочитать некоторые соответствующие разделы Спецификации DWARF и использовать библиотеку, такую как libdw (которая является частью elfutils).