Go to main content
Oracle® Solaris 11.3 リンカーとライブラリガイド

印刷ビューの終了

更新: 2015 年 10 月
 
 

圧縮デバッグセクション

補助オブジェクトで説明しているように、オブジェクトには、割り当て可能割り当て不可の両方のセクションが含まれます。割り当て可能なセクションは、実行可能コードとそのコードが実行時に必要とするデータが含まれているセクションです。割り当て不可のセクションには、実行時にオブジェクトを実行するために必要でない補足的な情報が含まれています。これらのセクションは、デバッガおよびほかの可観測性ツールの操作をサポートし、一般にデバッグセクションと呼ばれます。

要求されたデバッグ情報のレベルに応じて、デバッグセクションは記述されたコードに比例して非常に大きくなる可能性があります。これらのセクションを別のファイルに書き出す補助オブジェクトが、これらの大きなセクションを処理できる 1 つのメカニズムになります。圧縮デバッグセクションが、デバッグセクションのサイズを縮小するためのもう 1 つの補完的なオプションになります。

デバッグセクションは、業界標準の ZLIB 圧縮ライブラリで圧縮されます。ZLIB のドキュメントは、http://www.zlib.net/ にあります。

リンカーは、入力オブジェクト内の圧縮デバッグセクションを検出すると自動的にこれらのセクションを解凍します。この操作は、リンカーのユーザーに対して透過的で、特別なアクションは必要ありません。

デフォルトでは、リンカーは、出力オブジェクトのデバッグセクションを圧縮しません。出力ファイルのデバッグセクションの圧縮を有効にするには、–z compress-debug-sections オプションを使用します。

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

cmp-type では次の値が認識されます。

none

圧縮は行われません。このオプションは、–z compress-sections オプションを指定しない場合と同等です。

zlib

Compress candidate sections using ZLIB 圧縮を使用して候補セクションを圧縮します。結果の出力セクションでは、圧縮を使用していることがわかるように、SHF_COMPRESSED セクションフラグが設定されます。

zlib-gnu

GNU セクション圧縮形式を使用して、ZLIB 圧縮を使ってすべての候補セクションを圧縮します。この形式の場合、候補セクションの名前は .debug で始まっている必要があります。結果となる出力セクションの名前は、圧縮を使用していることがわかるように、.zdebug で始まる名前に変更されます。

cmp-type を省略した場合は zlib スタイルが使用されます。

圧縮形式のほうが元の非圧縮データよりも大きくなるセクションでは、圧縮は自動的にスキップされます。

あるセクションが圧縮の候補となるためには、そのセクションは割り当て不可能であり、かつ次のいずれかのクラスに属している必要があります。

annotate

注釈セクションには、メモリーアクセスツールおよびカバレージ関連ツールによって使用される情報が示されます。これらのセクションは、SHT_SUNW_ANNOTATE セクションタイプを指定することで識別します。

debug

デバッグセクションは、.compcom.line.stab*.debug*、または .zdebug* のセクション名を付けることによって識別されます。また、これらのセクションは、SHT_PROGBITS または SHT_SUNW_DEBUG* セクションタイプを指定することでも識別されます。

zlib-gnu 圧縮タイプは、.debug で始まる名前を持つセクションに制限されます。zlib-gnu を使用する場合、そうでなければ圧縮の候補となったであろうセクションは圧縮されません。ベースとなる ZLIB 圧縮は zlib スタイルと zlib-gnu スタイルとで同じなので、どちらの形式でも特定の入力セクションの圧縮量は同じになります。2 つのスタイルの違いは、候補セクションの選択、圧縮ヘッダーの形式、および圧縮セクションの識別方法、にあります。セクションの圧縮を参照してください。zlib-gnu スタイルを使用する必要性が特にないかぎり、より一般的なデフォルトの zlib スタイルをお勧めします。

次のプログラムは、圧縮されたデバッグセクションの使用方法について説明します。比較するために、プログラムは圧縮なしで 1 回、圧縮して 1 回の合計 2 回構築されます。

$ 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 セクションは、元の圧縮されていない形式よりも大きくなるので、圧縮しないまま残されます。

圧縮のコストと利点

圧縮デバッグセクションの主な利点は、オブジェクトのサイズを削減できることです。ただし、圧縮により、開発のすべての段階で実行時およびメモリー使用におけるコストが増加します。

  • コンパイラは、非圧縮形式で各デバッグセクションを生成し、圧縮バージョン用に追加のメモリーを割り当て、圧縮を実行する必要があります。

  • 入力オブジェクトを読み取ると、リンカーは圧縮データをメモリーに読み込み、非圧縮データを保持するための追加のメモリーを割り当て、解凍を実行します。

  • 出力時には、リンカーは生成されるデバッグセクションの非圧縮バージョンを作成する必要があります。圧縮が必要な場合、圧縮バージョンの作成に追加のメモリーと時間が費やされます。

  • デバッガは、圧縮デバッグセクションを含むオブジェクトを読み取ると、解凍したデータを保持するために追加のメモリーを割り当てて、解凍を実行する必要があります。

さらに、圧縮デバッグセクションは小さなファイルは対応できますが、大量の情報には対応できません。一般的な例としては、含まれる 32 ビットファイルのオフセットおよびサイズを使用するために基本的に 4G バイトに制限されている、32 ビットオブジェクトがあります。デバッグデータを圧縮すると、より多くのデバッグ情報を生成できると想定される場合があります。ただし、32 ビットデバッグデータの形式には 32 ビットオフセットなども含まれ、非圧縮形式では 4G バイトに論理的に制約されます。

これらの理由から、一般的な開発では圧縮デバッグセクションはお勧めしません。このような開発では通常、コンパイル/リンク/デバッグのサイクル速度がデバッグデータを縮小する利点よりも重要になるからです。圧縮デバッグセクションは、ディスク領域が十分でない場合や、広範にコピーされめったにデバッグされない実稼働オブジェクトでは役立つことがあります。