其他分享
首页 > 其他分享> > c – gdb从哪里获取代码行?

c – gdb从哪里获取代码行?

作者:互联网

当我用-g编译程序并获得核心转储时,我可以使用gdb读取可执行文件和核心转储来调试程序在崩溃之前遇到的情况. gdb提供的功能之一是list选项,可以列出使用可执行文件和核心转储编译的源代码.我使用字符串-a与可执行文件和核心转储,我甚至找不到if 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) break main
(gdb) run
(gdb) list
1       in bla.c

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

$objdump -Wi -wa ./a.out 

./a.out:     file format elf64-x86-64
./a.out

Contents of the .debug_info section:

  Compilation Unit @ offset 0x0:
   Length:        0x4e (32-bit)
   Version:       4
   Abbrev Offset: 0x0
   Pointer Size:  8
 : Abbrev Number: 1 (DW_TAG_compile_unit)
       DW_AT_producer    : (indirect string, offset: 0x0): GNU C 4.9.1 -mtune=generic -march=x86-64 -g
       DW_AT_language    : 1        (ANSI C)
       DW_AT_name        : (indirect string, offset: 0x59): bla.c
       DW_AT_comp_dir    : (indirect string, offset: 0x31): /home/myself/temp/bla
       DW_AT_low_pc      : 0x4004b6
       DW_AT_high_pc     : 0xb
       DW_AT_stmt_list   : 0x0
 : Abbrev Number: 2 (DW_TAG_subprogram)
       DW_AT_external    : 1
       DW_AT_name        : (indirect string, offset: 0x2c): main
       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 byte block: 9c         (DW_OP_call_frame_cfa)
       DW_AT_GNU_all_call_sites: 1
 : Abbrev Number: 3 (DW_TAG_base_type)
       DW_AT_byte_size   : 4
       DW_AT_encoding    : 5        (signed)
       DW_AT_name        : int
 : Abbrev Number: 0

每个DW_TAG_compile_unit都有关于源文件名和路径的信息,用于查找相关的源文件.

我想你自己做这一切,你应该阅读DWARF specifications的一些相关部分并使用libdw这个库(这是elfutils的一部分).

标签:c-2,linux,gcc,gdb,dwarf
来源: https://codeday.me/bug/20190628/1319042.html