gcc会为全局变量生成不必要的调试符号吗?

时间:2018-08-08 05:26:22

标签: c gcc debug-symbols

在我们的项目中,我们从gcc 5.3迁移到gcc 7.3,发现调试符号增加了很多;经过一番挖掘后,我发现gcc 7.3生成了不必要的全局变量调试符号(我想,如果我错了,请纠正我),因为我们声明了很多全局变量,并且很多c文件都包含它们,调试符号的大小最终的ELF积累了巨大的价值。

是否有gcc开关可以解决此问题,而无需更改全局变量的使用?

编辑1

"-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;

GCC 5.5,在test.c中没有不必要的调试符号“ __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

GCC 7.3,test.c中不必要的调试符号“ __my_unused”

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,没有这种问题。

0 个答案:

没有答案