When I compile a program with -g and get a core dump I can use gdb
to read the executable and the core dump to debug the situation the program run into before it crashed. One of the features gdb
offers is the list
option, it is possible to list the source code which was compiled using the executable and the core dump. I used strings -a
with the executable and the core dump and I couldn't find even one if
or for
statements while I'm sure the code has plenty of them. So where does the code is coming from? I compile the code on one computer and run it on different one, so the source code is not available on the computer where the core dump is generated, and it doesn't seem to be inside the executable or the core dump. Any suggestions? I really want to print all the source code from the executable and from the core dump, is it possible? I mean without running gdb
, I'm sure it is possible to write a script which uses gdb and that can list the entire code but I'm interested in doing it myself without gdb
because I want to understand from where the source code is taken how it is formatted, I want o know as much as possible about it.
GDB allows you to do things like run the program up to a certain point then stop and print out the values of certain variables at that point, or step through the program one line at a time and print out the values of each variable after executing each line. GDB uses a simple command line interface.
Run the code by typing “run or r”. If you haven't set any breakpoints, run command will simply execute the full program. 11. To see the value of variable, type “print variable_name or p variable_name“.
The line information is located in the .debug_line
DWARF sections 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
This sections maps instruction pointer addresses to line numbers in a given file.
In order to find the content of the file, you need to be able to finds the relevant source file. If you move/rename the source 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 has some information on the path where the source file was when it was compiled which may be used to find the relevant 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 path which is used to find the relevant source file.
I you want to do it all by yourself, you should probably read some relevant parts of the DWARF specifications and use a library such as libdw (which is a part of elfutils).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With