Oracle® Solaris 11.2 链接程序和库指南

退出打印视图

更新时间: 2014 年 7 月
 
 

压缩调试节

辅助目标文件中所述,目标文件同时包含可分配不可分配的节。可分配节是包含可执行代码和运行时该代码需要的数据的节。不可分配节包含补充信息,在运行时执行目标文件时这些信息不是必需的。这些节支持调试器和其他观察工具的操作,(非正式情况下)也称为调试节。

根据请求的调试信息级别,调试节相对于其说明的代码来说可能会变得非常大。将这些节写入单独文件的辅助目标文件提供了一种处理这些大型节的机制。而压缩调试节提供了第二种补充性的方法,可减小调试节大小。

调试节是使用行业标准的 ZLIB 压缩库进行压缩的。可在以下网址找到 ZLIB 的文档:http://www.zlib.net/

链接编辑器可识别输入目标文件中的压缩调试节,并可自动解压缩这些节。此操作对链接编辑器的用户是透明的,且无需特殊操作。

缺省情况下,链接编辑器不压缩输出目标文件中的调试节。使用 –z compress-debug-sections 选项启用对输出文件中调试节的压缩。

$ cc .... -z compress-sections[=cmp-type] ....

可识别 cmp-type 的以下值。

none

不进行压缩。此选项等同于未指定 –z compress-sections 选项。

zlib

使用 ZLIB 压缩对候选节进行压缩。生成的输出节将设置 SHF_COMPRESSED 节标志来标识使用了压缩。

zlib-gnu

使用 ZLIB 压缩、使用 GNU 节压缩格式来压缩所有候选节。此格式要求候选节具有以 .debug 开头的名称。生成的输出节将重命名为以 .zdebug 开头来标识使用了压缩。

如果省略了 cmp-type,则使用 zlib 样式。

对任何节进行压缩时,如果压缩格式下的大小超过原始未压缩数据,则此压缩将被静默跳过。

要成为压缩候选项,节必须是不可分配的并且属于以下类之一。

annotate

注释节提供由内存访问工具和与覆盖范围相关的工具使用的信息。这些部分通过 SHT_SUNW_ANNOTATE 节类型来进行标识。

debug

调试节通过 .compcom.line.stab*.debug*.zdebug* 节名称来进行标识。这些节还通过 SHT_PROGBITSSHT_SUNW_DEBUG* 节类型进行标识。

zlib-gnu 压缩类型仅限于名称以 .debug 开头的节。使用 zlib-gnu 时,将不压缩本将是压缩候选项的节。对于 zlibzlib-gnu 样式,底层 ZLIB 压缩是相同的,这两种格式对于给定输入节提供相同压缩量。这两种样式的不同之处在于候选节选择、压缩头的格式以及如何标识压缩的节。请参见节压缩。除非特别要求使用 zlib-gnu 样式,否则推荐使用更通用的缺省 zlib 样式。

以下程序演示如何使用压缩调试节。为了进行比较,程序构建了两次,一次无压缩,另一次进行了压缩。

$ cat hello.c
#include    <stdio.h>

int
main(int argc, char **argv) 
{ 
        (void) printf("hello, world\n");
        return (0);
}
% cc -g hello.c -o a.out.uncompressed
% cc -g hello.c -o a.out.compressed -z compress-sections

现在可比较未压缩调试节和压缩调试节的节头。

$ elfdump -c a.out.uncompressed
....
Section Header[24]:  sh_name: .debug_info
    sh_addr:      0               sh_flags:   0
    sh_size:      0x17b           sh_type:    [ SHT_PROGBITS ]
    ....

Section Header[25]:  sh_name: .debug_line
    sh_addr:      0               sh_flags:   0
    sh_size:      0x4f            sh_type:    [ SHT_PROGBITS ]
    ....

Section Header[26]:  sh_name: .debug_abbrev
    sh_addr:      0               sh_flags:   0
    sh_size:      0x7c            sh_type:    [ SHT_PROGBITS ]
    ....

Section Header[27]:  sh_name: .debug_pubnames
    sh_addr:      0               sh_flags:   0
    sh_size:      0x1b            sh_type:    [ SHT_PROGBITS ]
    ....

$ elfdump -c a.out.compressed
....
Section Header[24]:  sh_name: .debug_info
    sh_addr:      0               sh_flags:   [ SHF_COMPRESSED ]
    sh_size:      0x14f           sh_type:    [ SHT_PROGBITS ]
    ....
    ch_size:      0x196           ch_type:    [ ELFCOMPRESS_ZLIB ]
    ch_addralign: 0x1       

Section Header[25]:  sh_name: .debug_line
    sh_addr:      0               sh_flags:   0
    sh_size:      0x4f            sh_type:    [ SHT_PROGBITS ]
    ....

Section Header[26]:  sh_name: .debug_abbrev
    sh_addr:      0               sh_flags:   [ SHF_COMPRESSED ]
    sh_size:      0x79            sh_type:    [ SHT_PROGBITS ]
    ....
    ch_size:      0x7c            ch_type:    [ ELFCOMPRESS_ZLIB ]
    ch_addralign: 0x1       

Section Header[27]:  sh_name: .debug_pubnames
    sh_addr:      0               sh_flags:   0
    sh_size:      0x1b            sh_type:    [ SHT_PROGBITS ]
    ....

各个压缩节 .debug_info.debug_abbrev 都使用 SHF_COMPRESSED 节标志进行标识。此外,节头信息带有压缩头结构信息。ch_size 和 ch_addralign 字段提供未压缩数据的大小和对齐要求。请参见节压缩

.debug_line.debug_pubnames 节的压缩格式大于其原始未压缩格式,因此保持不压缩的状态。