Skip to main content

Reference: Debug Information Symbols

Debug info allow debuggers like GDB to provide insight into a program's runtime by attaching debug info to the executable. This is very useful when debugging issues, as you can inspect a running program with the added context of variable names and file info. Memfault uses debug info to build and display backtraces captured on your device.

Enabling Debug Info

Debug info can be enabled on most C compilers by passing the -g compiler flag. You can view an in-depth breakdown of the -g flag and some other exciting options in the GCC manual.

In Linux environments, you can generate a separate archive containing all symbols for your program and any dynamically linked programs. See our guide here for Yocto Linux.

Checking For Debug Info

There are a few ways to check if your program has debug info enabled. The most straightforward method is to use the file command. On an ELF with debug info you should see not stripped in the output:

file output.elf
output.elf: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, BuildID[sha1]=ea7be47d5109b4ff117a62fa309422b73d8c4daa, with debug_info, not stripped

Additionally you could use the readelf command to check if .debug_* sections are present:

readelf -SW output.elf
There are 43 section headers, starting at offset 0x5e1e2c:

Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] rom_start PROGBITS 0000d200 000140 0000dc 00 WAX 0 0 4
[ 2] text PROGBITS 0000d2e0 000220 039e48 00 AX 0 0 16
[ 3] .ARM.exidx ARM_EXIDX 00047128 03a068 000008 00 AL 2 0 4
[ 4] initlevel PROGBITS 00047130 03a070 000100 00 A 0 0 4
[ 5] devices PROGBITS 00047230 03a170 0001c0 00 A 0 0 4
[ 6] sw_isr_table PROGBITS 000473f0 03a330 000138 00 WA 0 0 4
[ 7] device_handles PROGBITS 00047528 03a468 00008c 00 A 0 0 2
[ 8] bt_l2cap_fixed_chan_area PROGBITS 000475b4 03a4f4 000024 00 A 0 0 4
[ 9] bt_gatt_service_static_area PROGBITS 000475d8 03a518 000030 00 A 0 0 4
[10] log_const_sections PROGBITS 00047608 03a548 000338 00 A 0 0 4
[11] zephyr_dbg_info PROGBITS 00047940 03a880 00003c 00 WA 0 0 4
[12] settings_handler_static_area PROGBITS 0004797c 03a8bc 000050 00 A 0 0 4
[13] rodata PROGBITS 00047a00 03a940 00cf34 00 A 0 0 64
[14] .ramfunc PROGBITS 20000000 049010 000000 00 W 0 0 1
[15] datas PROGBITS 20000000 047878 00108a 00 WA 0 0 8
[16] device_states PROGBITS 2000108c 048904 000040 00 WA 0 0 4
[17] pm_device_slots NOBITS 200010cc 048944 000014 00 WA 0 0 4
[18] _static_thread_data_area PROGBITS 200010e0 048948 000030 00 WA 0 0 4
[19] k_timer_area PROGBITS 20001110 048978 0002d8 00 WA 0 0 8
[20] k_mem_slab_area PROGBITS 200013e8 048c50 0000a0 00 WA 0 0 4
[21] k_heap_area PROGBITS 20001488 048cf0 000048 00 WA 0 0 4
[22] k_mutex_area PROGBITS 200014d0 048d38 000064 00 WA 0 0 4
[23] k_msgq_area PROGBITS 20001534 048d9c 000034 00 WA 0 0 4
[24] k_sem_area PROGBITS 20001568 048dd0 000078 00 WA 0 0 4
[25] k_queue_area PROGBITS 200015e0 048e48 000038 00 WA 0 0 4
[26] _net_buf_pool_area PROGBITS 20001618 048e80 00016c 00 WA 0 0 4
[27] bss NOBITS 200017c0 049040 006e71 00 WA 0 0 64
[28] noinit NOBITS 20008638 049040 006696 00 WA 0 0 8
[29] .note.gnu.build-id NOTE 000560b8 048fec 000024 00 A 0 0 4
[30] .comment PROGBITS 00000000 049010 000020 01 MS 0 0 1
[31] .debug_aranges PROGBITS 00000000 049030 006e98 00 0 0 8
[32] .debug_info PROGBITS 00000000 04fec8 340e45 00 0 0 1
[33] .debug_abbrev PROGBITS 00000000 390d0d 03af49 00 0 0 1
[34] .debug_line PROGBITS 00000000 3cbc56 0b6ba3 00 0 0 1
[35] .debug_frame PROGBITS 00000000 4827fc 01578c 00 0 0 4
[36] .debug_str PROGBITS 00000000 497f88 034936 01 MS 0 0 1
[37] .debug_loc PROGBITS 00000000 4cc8be 0b292a 00 0 0 1
[38] .debug_ranges PROGBITS 00000000 57f1e8 0255a8 00 0 0 8
[39] .ARM.attributes ARM_ATTRIBUTES 00000000 5a4790 000039 00 0 0 1
[40] .symtab SYMTAB 00000000 5a47cc 026a00 10 41 7078 4
[41] .strtab STRTAB 00000000 5cb1cc 016a2e 00 0 0 1
[42] .shstrtab STRTAB 00000000 5e1bfa 00022f 00 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
L (link order), O (extra OS processing required), G (group), T (TLS),
C (compressed), x (unknown), o (OS specific), E (exclude),
D (mbind), y (purecode), p (processor specific)

Frequently Asked Questions

Does debug info make my program larger?

While including debug symbols will make your generated ELF or binary larger, in general, it does not affect the size of the loaded program. This is especially true in an MCU environment where debug info is stripped before it is loaded onto the device.

Does debug info make my program slower?

Debug symbols and optimization levels are separate configurations that do not affect each other. Enabling debug info has no effect on execution surface of your program.

Optimization levels can, however, make it more difficult to step through your program as certain names can be mangled, or functions can be inlined. Additionally, when analyzing coredumps certain variables may be optimized out, or missing call frames in the stack trace.