gdb 从哪里获取代码行

From where does gdb take the code lines?

本文关键字:取代码 获取 gdb      更新时间:2023-10-16

当我使用 -g 编译程序并获得核心转储时,我可以使用gdb读取可执行文件和核心转储来调试程序在崩溃之前遇到的情况。gdb提供的功能之一是list选项,可以列出使用可执行文件和核心转储编译的源代码。我将strings -a与可执行文件和核心转储一起使用,我什至找不到一个iffor语句,而我确信代码有很多语句。那么代码是从哪里来的呢?我在一台计算机上编译代码并在另一台计算机上运行它,因此源代码在生成核心转储的计算机上不可用,并且它似乎不在可执行文件或核心转储中。有什么建议吗?我真的想打印可执行文件和核心转储中的所有源代码,可以吗?我的意思是不运行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.cgdb ./a.out(GDB) 中断主要(GDB) 运行(GDB) 列表1 在 bla.c

.debug_info DWARF 部分包含一些有关源文件编译时路径的信息,这些信息可用于查找相关文件:

$objdump -wi -wa ./a.out./a.out: 文件格式 elf64-x86-64./a.out.debug_info部分的内容:  编译单元 @ 偏移量0x0:   长度:0x4e(32 位)   版本: 4   缩写偏移量:0x0   指针大小:8 : 缩写号: 1 (DW_TAG_compile_unit)       DW_AT_producer : (间接字符串, 偏移量: 0x0): GNU C 4.9.1 -mtune=generic -march=x86-64 -g       DW_AT_language : 1 (ANSI C)       DW_AT_name :(间接字符串,偏移量:0x59):bla.c       DW_AT_comp_dir : (间接字符串, 偏移量: 0x31):/home/myself/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 的一部分)这样的库。