压缩DWARF数据

与DWARF v1相比,DWARF新版本使用的编码方案大大减少了调试信息的大小。但不幸的是,编译器生成的调试信息仍然很大,通常大于可执行代码和数据的存储占用。DWARF新版本提供了进一步减少调试数据大小的方法,比如使用zlib数据压缩。

下面是一个生产环境服务(编译后大约147MB),即使采用了DWARF v4并且开启了DWARF数据压缩之后 (Flags==C),编译完也有147MB。构建后文件尺寸大,是多方面原因,比如这里的Go程序使用静态链接,符号表信息,调试信息也都有保留。

root🦀 bin $ readelf -S grpc_admin_svr
There are 36 section headers, starting at offset 0x238:

Section Headers:
  [Nr] Name              Type             Address           Offset
       Size              EntSize          Flags  Link  Info  Align
       ...
  [24] .debug_abbrev     PROGBITS         0000000000000000  0688d000
       0000000000000135  0000000000000000   C       0     0     1
  [25] .debug_line       PROGBITS         0000000000000000  0688d135
       00000000006538d5  0000000000000000   C       0     0     1
  [26] .debug_frame      PROGBITS         0000000000000000  06ee0a0a
       000000000012ada4  0000000000000000   C       0     0     1
  [27] .debug_gdb_script PROGBITS         0000000000000000  0700b7ae
       0000000000000030  0000000000000000           0     0     1
  [28] .debug_info       PROGBITS         0000000000000000  0700b7de
       0000000000ace1cb  0000000000000000   C       0     0     1
  [29] .debug_loc        PROGBITS         0000000000000000  07ad99a9
       0000000000881add  0000000000000000   C       0     0     1
  [30] .debug_ranges     PROGBITS         0000000000000000  0835b486
       00000000004836ee  0000000000000000   C       0     0     1
  ...

那我们去掉DWARF数据看看能节省多少存储占用,使用objcopy去掉所有的DWARF debug sections,然后查看文件大小,32MB!!!

root🦀 bin $ objcopy --strip-debug grpc_admin_svr grpc_admin_svr.stripped
root🦀 bin $ ll -h
total 262M
drwxr-xr-x 2 root root 4.0K May 18 11:34 ./
drwxr-xr-x 4 root root 4.0K Apr 28 16:05 ../
-rwxr-xr-x 1 root root 147M May 12 13:01 grpc_admin_svr
-rwxr-xr-x 1 root root 115M May 18 11:34 grpc_admin_svr.stripped

32MB还是有点大的,大多数编程语言是默认不生成调试信息的,Go语言是个例外。

golang/go issues也有讨论是否应该默认关闭DWARF数据生成。至于Go新版本是否会默认关闭DWARF生成,很可能不会,因为这也会增加调试的成本,制品库、代码版本、调试符号信息一一对应的管理成本。在存储成本低廉的今天,默认关闭DWARF调试信息生成的策略,可能是一个按下葫芦起了瓢的做法,对实践并不见的特别有价值。

当然如果你想显示关闭DWARF调试信息生成,可以通过 go build -ldflags='-w' 来关闭调试信息生成。

results matching ""

    No results matching ""