Where does gdb get its lines of code from?

When I compile the program with -g and get a kernel dump, I can use gdb

to read the executable and the main dump to debug the situation the program was running in before it crashed. One of the possibilities gdb

offers the option list

, you can specify the source code that was compiled using an executable file and a core dump. I have used strings -a

with an executable and a core dump and I could not find any statement if

orfor

, while I'm sure there are a lot of them in the code. So where does this code come from? I am compiling the code on one machine and running it on another, so the source code is not available on the machine where the kernel dump is generated and it does not seem to be inside the executable or kernel dump. Any suggestions? I really want to print all the source code from the executable and from the kernel dump, is this possible? I mean without running gdb

, I'm sure it is possible to write a script that uses gdb and that can display all the code, but I am interested in doing it myself without gdb

, because I want to understand from where the source code comes from, how it is formatted, i want to know as much as possible about it.

+3


source to share


1 answer


The line information is in the .debug_line

DWARF section of the executable:

$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

      

These sections display the addresses of pointers to pointers to line numbers in the specified file.

To find the contents of a file, you need to find the corresponding source file. If you move / rename the original file, GDB will not be able to print the source code:

mv bla.c bla2.c
gdb ./a.out
(gdb) break main
(gdb) run
(gdb) list
1 in bla.c


The .debug_info

DWARF sections have information about the path in which the source file was when it was compiled, which can be used to find the corresponding file:

$ 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

Each DW_TAG_compile_unit

has information about the source file name and the path that is used to find the corresponding source file.

I want to do this myself, you should probably read some relevant parts of the DWARF spec and use a library like libdw (which is part of elfutils ).

+3


source







All Articles