在我们的项目中,我们从gcc 5.3迁移到gcc 7.3,发现调试符号增加了很多;经过一番挖掘后,我发现gcc 7.3生成了不必要的全局变量调试符号(我想,如果我错了,请纠正我),因为我们声明了很多全局变量,并且很多c文件都包含它们,调试符号的大小最终的ELF积累了巨大的价值。
是否有gcc开关可以解决此问题,而无需更改全局变量的使用?
"-O3" or "-Os", "-feliminate-unused-debug-types" does not help.
以下是显示问题的示例(在Ubuntu 18.04上,使用gcc 5.5和gcc 7.3): 示例代码:
### test.c
#include "global.h"
int
main()
{
return 0;
}
###global.c
#include "global.h"
int __my_unused = 1;
###global.h
extern int __my_unused;
root@b-test:/tmp# gcc-5 -g -O2 test.c global.c
root@b-test:/tmp# readelf -wi a.out
Contents of the .debug_info section:
Compilation Unit @ offset 0x0:
Length: 0x4a (32-bit)
Version: 4
Abbrev Offset: 0x0
Pointer Size: 8
<0><b>: Abbrev Number: 1 (DW_TAG_compile_unit)
<c> DW_AT_producer : (indirect string, offset: 0x0): GNU C11 5.5.0 20171010 -mtune=generic -march=x86-64 -g -O2 -fstack-protector-strong
<10> DW_AT_language : 12 (ANSI C99)
<11> DW_AT_name : (indirect string, offset: 0x59): test.c
<15> DW_AT_comp_dir : (indirect string, offset: 0x54): /tmp
<19> DW_AT_ranges : 0x0
<1d> DW_AT_low_pc : 0x0
<25> DW_AT_stmt_list : 0x0
<1><29>: Abbrev Number: 2 (DW_TAG_subprogram)
<2a> DW_AT_external : 1
<2a> DW_AT_name : (indirect string, offset: 0x60): main
<2e> DW_AT_decl_file : 1
<2f> DW_AT_decl_line : 3
<30> DW_AT_type : <0x46>
<34> DW_AT_low_pc : 0x530
<3c> DW_AT_high_pc : 0x3
<44> DW_AT_frame_base : 1 byte block: 9c (DW_OP_call_frame_cfa)
<46> DW_AT_GNU_all_call_sites: 1
<1><46>: Abbrev Number: 3 (DW_TAG_base_type)
<47> DW_AT_byte_size : 4
<48> DW_AT_encoding : 5 (signed)
<49> DW_AT_name : int
<1><4d>: Abbrev Number: 0
Compilation Unit @ offset 0x4e:
Length: 0x36 (32-bit)
Version: 4
Abbrev Offset: 0x37
Pointer Size: 8
<0><59>: Abbrev Number: 1 (DW_TAG_compile_unit)
<5a> DW_AT_producer : (indirect string, offset: 0x0): GNU C11 5.5.0 20171010 -mtune=generic -march=x86-64 -g -O2 -fstack-protector-strong
<5e> DW_AT_language : 12 (ANSI C99)
<5f> DW_AT_name : (indirect string, offset: 0x65): global.c
<63> DW_AT_comp_dir : (indirect string, offset: 0x54): /tmp
<67> DW_AT_stmt_list : 0x39
<1><6b>: Abbrev Number: 2 (DW_TAG_variable)
<6c> DW_AT_name : (indirect string, offset: 0x6e): __my_unused
<70> DW_AT_decl_file : 1
<71> DW_AT_decl_line : 2
<72> DW_AT_type : <0x80>
<76> DW_AT_external : 1
<76> DW_AT_location : 9 byte block: 3 10 10 20 0 0 0 0 0 (DW_OP_addr: 201010)
<1><80>: Abbrev Number: 3 (DW_TAG_base_type)
<81> DW_AT_byte_size : 4
<82> DW_AT_encoding : 5 (signed)
<83> DW_AT_name : int
<1><87>: Abbrev Number: 0
root@b-test:/tmp# gcc-7 -g -O2 test.c global.c
root@b-test:/tmp# readelf -wi a.out
Contents of the .debug_info section:
Compilation Unit @ offset 0x0:
Length: 0x55 (32-bit)
Version: 4
Abbrev Offset: 0x0
Pointer Size: 8
<0><b>: Abbrev Number: 1 (DW_TAG_compile_unit)
<c> DW_AT_producer : (indirect string, offset: 0xc): GNU C11 7.3.0 -mtune=generic -march=x86-64 -g -O2 -fstack-protector-strong
<10> DW_AT_language : 12 (ANSI C99)
<11> DW_AT_name : (indirect string, offset: 0x5c): test.c
<15> DW_AT_comp_dir : (indirect string, offset: 0x57): /tmp
<19> DW_AT_ranges : 0x0
<1d> DW_AT_low_pc : 0x0
<25> DW_AT_stmt_list : 0x0
<1><29>: Abbrev Number: 2 (DW_TAG_variable)
<2a> DW_AT_name : (indirect string, offset: 0x0): __my_unused
<2e> DW_AT_decl_file : 2
<2f> DW_AT_decl_line : 1
<30> DW_AT_type : <0x34>
<34> DW_AT_external : 1
<34> DW_AT_declaration : 1
<1><34>: Abbrev Number: 3 (DW_TAG_base_type)
<35> DW_AT_byte_size : 4
<36> DW_AT_encoding : 5 (signed)
<37> DW_AT_name : int
<1><3b>: Abbrev Number: 4 (DW_TAG_subprogram)
<3c> DW_AT_external : 1
<3c> DW_AT_name : (indirect string, offset: 0x63): main
<40> DW_AT_decl_file : 1
<41> DW_AT_decl_line : 3
<42> DW_AT_type : <0x34>
<46> DW_AT_low_pc : 0x4f0
<4e> DW_AT_high_pc : 0x3
<56> DW_AT_frame_base : 1 byte block: 9c (DW_OP_call_frame_cfa)
<58> DW_AT_GNU_all_call_sites: 1
<1><58>: Abbrev Number: 0
Compilation Unit @ offset 0x59:
Length: 0x3d (32-bit)
Version: 4
Abbrev Offset: 0x48
Pointer Size: 8
<0><64>: Abbrev Number: 1 (DW_TAG_compile_unit)
<65> DW_AT_producer : (indirect string, offset: 0xc): GNU C11 7.3.0 -mtune=generic -march=x86-64 -g -O2 -fstack-protector-strong
<69> DW_AT_language : 12 (ANSI C99)
<6a> DW_AT_name : (indirect string, offset: 0x68): global.c
<6e> DW_AT_comp_dir : (indirect string, offset: 0x57): /tmp
<72> DW_AT_stmt_list : 0x45
<1><76>: Abbrev Number: 2 (DW_TAG_variable)
<77> DW_AT_name : (indirect string, offset: 0x0): __my_unused
<7b> DW_AT_decl_file : 1
<7c> DW_AT_decl_line : 1
<7d> DW_AT_type : <0x81>
<81> DW_AT_external : 1
<81> DW_AT_declaration : 1
<1><81>: Abbrev Number: 3 (DW_TAG_base_type)
<82> DW_AT_byte_size : 4
<83> DW_AT_encoding : 5 (signed)
<84> DW_AT_name : int
<1><88>: Abbrev Number: 4 (DW_TAG_variable)
<89> DW_AT_specification: <0x76>
<8d> DW_AT_decl_file : 2
<8e> DW_AT_decl_line : 2
<8f> DW_AT_location : 9 byte block: 3 10 10 20 0 0 0 0 0 (DW_OP_addr: 201010)
<1><99>: Abbrev Number: 0
我也尝试了gcc 6.4和8.0,同样的问题;对于gcc 5和clang 5和6,没有这种问题。