GCC -g 参数
获取更多嵌入式、Linux学习资料,获取独家嵌入式Linux学习路线地图,欢迎加群:398294860,观看更专业、更系统地嵌入式视频教程,请关注:wanglitao.taobao.com
程序的编译一般分为两种模式:debug模式和release模式。
软件在开发阶段,需要不断地调试,甚至源码级单步调试,此时建议使用debug模式编译,生成的可执行文件中包含了大量的调试信息,可以方便我们使用gdb等调试器进行源码级地调试:比如单步、在源码中设置断点等。
使用调试模式生成的可执行文件因为包含大量的调试信息,所以文件体系会比release模式大。等开发结束,发布软件时,建议使用release模式,生成的可执行文件体积就比较小了。
使用gcc -g 选项,可以生成一个debug模式的可执行文件:
# gcc -g hello.c
# readelf -S a.out
There are 36 section headers, starting at offset 0x4208:
Section Headers:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
[ 0] NULL 0000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
[ 1] .interp PROGBITS 0000000000000318 00000318
000000000000001c 0000000000000000 A 0 0 1
[ 2] .note.gnu.propert NOTE 0000000000000338 00000338
0000000000000020 0000000000000000 A 0 0 8
[ 3] .note.gnu.build-i NOTE 0000000000000358 00000358
0000000000000024 0000000000000000 A 0 0 4
[ 4] .note.ABI-tag NOTE 000000000000037c 0000037c
0000000000000020 0000000000000000 A 0 0 4
[ 5] .gnu.hash GNU_HASH 00000000000003a0 000003a0
0000000000000024 0000000000000000 A 6 0 8
[ 6] .dynsym DYNSYM 00000000000003c8 000003c8
00000000000000a8 0000000000000018 A 7 1 8
[ 7] .dynstr STRTAB 0000000000000470 00000470
0000000000000098 0000000000000000 A 0 0 1
[ 8] .gnu.version VERSYM 0000000000000508 00000508
000000000000000e 0000000000000002 A 6 0 2
[ 9] .gnu.version_r VERNEED 0000000000000518 00000518
0000000000000030 0000000000000000 A 7 1 8
[10] .rela.dyn RELA 0000000000000548 00000548
00000000000000c0 0000000000000018 A 6 0 8
[11] .rela.plt RELA 0000000000000608 00000608
0000000000000018 0000000000000018 AI 6 24 8
[12] .init PROGBITS 0000000000001000 00001000
000000000000001b 0000000000000000 AX 0 0 4
[13] .plt PROGBITS 0000000000001020 00001020
0000000000000020 0000000000000010 AX 0 0 16
[14] .plt.got PROGBITS 0000000000001040 00001040
0000000000000010 0000000000000010 AX 0 0 16
[15] .plt.sec PROGBITS 0000000000001050 00001050
0000000000000010 0000000000000010 AX 0 0 16
[16] .text PROGBITS 0000000000001060 00001060
0000000000000195 0000000000000000 AX 0 0 16
[17] .fini PROGBITS 00000000000011f8 000011f8
000000000000000d 0000000000000000 AX 0 0 4
[18] .rodata PROGBITS 0000000000002000 00002000
0000000000000004 0000000000000004 AM 0 0 4
[19] .eh_frame_hdr PROGBITS 0000000000002004 00002004
0000000000000044 0000000000000000 A 0 0 4
[20] .eh_frame PROGBITS 0000000000002048 00002048
0000000000000108 0000000000000000 A 0 0 8
[21] .init_array INIT_ARRAY 0000000000003db8 00002db8
0000000000000008 0000000000000008 WA 0 0 8
[22] .fini_array FINI_ARRAY 0000000000003dc0 00002dc0
0000000000000008 0000000000000008 WA 0 0 8
[23] .dynamic DYNAMIC 0000000000003dc8 00002dc8
00000000000001f0 0000000000000010 WA 7 0 8
[24] .got PROGBITS 0000000000003fb8 00002fb8
0000000000000048 0000000000000008 WA 0 0 8
[25] .data PROGBITS 0000000000004000 00003000
0000000000000010 0000000000000000 WA 0 0 8
[26] .bss NOBITS 0000000000004010 00003010
0000000000000008 0000000000000000 WA 0 0 1
[27] .comment PROGBITS 0000000000000000 00003010
000000000000002a 0000000000000001 MS 0 0 1
[28] .debug_aranges PROGBITS 0000000000000000 0000303a
0000000000000030 0000000000000000 0 0 1
[29] .debug_info PROGBITS 0000000000000000 0000306a
000000000000031f 0000000000000000 0 0 1
[30] .debug_abbrev PROGBITS 0000000000000000 00003389
00000000000000e8 0000000000000000 0 0 1
[31] .debug_line PROGBITS 0000000000000000 00003471
0000000000000111 0000000000000000 0 0 1
[32] .debug_str PROGBITS 0000000000000000 00003582
000000000000028b 0000000000000001 MS 0 0 1
[33] .symtab SYMTAB 0000000000000000 00003810
0000000000000690 0000000000000018 34 51 8
[34] .strtab STRTAB 0000000000000000 00003ea0
000000000000020d 0000000000000000 0 0 1
[35] .shstrtab STRTAB 0000000000000000 000040ad
000000000000015a 0000000000000000 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),
l (large), p (processor specific)
使用debug模式生成的可执行文件里,会有一些单独的section保存各种符号及调试信息,这些信息包含了二进制代码和源码之间的一一对应关系。通过这种对应关系,我们就可以实现源码级的单步调试和设置断点。
对比一下,release模式的可执行文件,你会发现:debug模式的可执行文件里有35个section,而release模式的可执行文件里只有30个section:
# gcc hello.c
# readelf -S a.out
There are 31 section headers, starting at offset 0x3980:
Section Headers:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
[ 0] NULL 0000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
[ 1] .interp PROGBITS 0000000000000318 00000318
000000000000001c 0000000000000000 A 0 0 1
[ 2] .note.gnu.propert NOTE 0000000000000338 00000338
0000000000000020 0000000000000000 A 0 0 8
[ 3] .note.gnu.build-i NOTE 0000000000000358 00000358
0000000000000024 0000000000000000 A 0 0 4
[ 4] .note.ABI-tag NOTE 000000000000037c 0000037c
0000000000000020 0000000000000000 A 0 0 4
[ 5] .gnu.hash GNU_HASH 00000000000003a0 000003a0
0000000000000024 0000000000000000 A 6 0 8
[ 6] .dynsym DYNSYM 00000000000003c8 000003c8
00000000000000a8 0000000000000018 A 7 1 8
[ 7] .dynstr STRTAB 0000000000000470 00000470
0000000000000098 0000000000000000 A 0 0 1
[ 8] .gnu.version VERSYM 0000000000000508 00000508
000000000000000e 0000000000000002 A 6 0 2
[ 9] .gnu.version_r VERNEED 0000000000000518 00000518
0000000000000030 0000000000000000 A 7 1 8
[10] .rela.dyn RELA 0000000000000548 00000548
00000000000000c0 0000000000000018 A 6 0 8
[11] .rela.plt RELA 0000000000000608 00000608
0000000000000018 0000000000000018 AI 6 24 8
[12] .init PROGBITS 0000000000001000 00001000
000000000000001b 0000000000000000 AX 0 0 4
[13] .plt PROGBITS 0000000000001020 00001020
0000000000000020 0000000000000010 AX 0 0 16
[14] .plt.got PROGBITS 0000000000001040 00001040
0000000000000010 0000000000000010 AX 0 0 16
[15] .plt.sec PROGBITS 0000000000001050 00001050
0000000000000010 0000000000000010 AX 0 0 16
[16] .text PROGBITS 0000000000001060 00001060
0000000000000195 0000000000000000 AX 0 0 16
[17] .fini PROGBITS 00000000000011f8 000011f8
000000000000000d 0000000000000000 AX 0 0 4
[18] .rodata PROGBITS 0000000000002000 00002000
0000000000000004 0000000000000004 AM 0 0 4
[19] .eh_frame_hdr PROGBITS 0000000000002004 00002004
0000000000000044 0000000000000000 A 0 0 4
[20] .eh_frame PROGBITS 0000000000002048 00002048
0000000000000108 0000000000000000 A 0 0 8
[21] .init_array INIT_ARRAY 0000000000003db8 00002db8
0000000000000008 0000000000000008 WA 0 0 8
[22] .fini_array FINI_ARRAY 0000000000003dc0 00002dc0
0000000000000008 0000000000000008 WA 0 0 8
[23] .dynamic DYNAMIC 0000000000003dc8 00002dc8
00000000000001f0 0000000000000010 WA 7 0 8
[24] .got PROGBITS 0000000000003fb8 00002fb8
0000000000000048 0000000000000008 WA 0 0 8
[25] .data PROGBITS 0000000000004000 00003000
0000000000000010 0000000000000000 WA 0 0 8
[26] .bss NOBITS 0000000000004010 00003010
0000000000000008 0000000000000000 WA 0 0 1
[27] .comment PROGBITS 0000000000000000 00003010
000000000000002a 0000000000000001 MS 0 0 1
[28] .symtab SYMTAB 0000000000000000 00003040
0000000000000618 0000000000000018 29 46 8
[29] .strtab STRTAB 0000000000000000 00003658
000000000000020d 0000000000000000 0 0 1
[30] .shstrtab STRTAB 0000000000000000 00003865
000000000000011a 0000000000000000 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),
l (large), p (processor specific)
多出来的.debug_str 、.debug_line、.debug_abbrev 、.debug_info 、.debug_aranges等section就是用来保存各种调试信息的。
《Linux三剑客》视频教程,从零开始快速掌握Linux开发常用的工具:Git、Makefile、vim、autotools、debug,免费赠送C语言视频教程,C语言项目实战:学生成绩管理系统。详情请点击淘宝链接:Linux三剑客