Откуда GDB берет строки кода?

Когда я компилирую программу с -g и получаю дамп ядра, я могу использовать gdb чтобы прочитать исполняемый файл и дамп ядра, чтобы отладить ситуацию, в которой запустилась программа до ее сбоя. Одна из особенностей gdb предложения это list опцию, можно перечислить исходный код, который был скомпилирован с использованием исполняемого файла и дампа ядра. я использовал strings -a с исполняемым файлом и дампом ядра, и я не смог найти ни одного if или же for заявления, пока я уверен, что в коде их много. Так откуда берется код? Я компилирую код на одном компьютере и запускаю его на другом, чтобы исходный код не был доступен на компьютере, где создается дамп ядра, и, похоже, он не находится внутри исполняемого файла или дампа ядра. Какие-либо предложения? Я действительно хочу напечатать весь исходный код из исполняемого файла и из дампа ядра, это возможно? Я имею в виду без бега gdbЯ уверен, что можно написать сценарий, который использует GDB и может перечислить весь код, но я заинтересован в том, чтобы сделать это самостоятельно без gdb потому что я хочу понять, откуда взят исходный код, как он отформатирован, я хочу узнать как можно больше об этом.

4

Решение

Информация о линии находится в .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).

3

Другие решения


По вопросам рекламы [email protected]