web-dev-qa-db-ja.com

開発中にデバッグシンボルをシステムライブラリに添付するためのベストプラクティスは?

私は、システムパッケージのデバッグバージョンをインストールしておくと非常に便利なプロジェクトの段階にあります。少なくともUbuntuでは、デバッグシンボルをライブラリに追加するのは簡単です。事実上、すべてのパッケージには、有用なバックトレースに必要なすべてのシンボルを提供する-dbgバリアントがあります。

しかし、私は現在Arch Linuxを使用しており、 一般的なコンセンサス はユーザーのmakepkg.confファイルを編集し、デバッグフラグを(C|CXX|CPP|LD)FLAGSに追加します。次に、パッケージを自分で再ビルドし、現在の最適化されたバージョンをデバッグビルドに置き換えます。まあ、それは「ソースベースの配布」で十分に公平だと思いますが、それはかなりすぐに退屈になります。

では、デバッグシンボルをシステムパッケージに添付するためのベストプラクティスは何ですか?他のパッケージャーはどのようにそれを行いますか?

stripがデバッグシンボルを抽出し、それらを外部ファイルに保存できることを確認したと思います。 gdbがバックトレース中にこれらのシンボルファイルを取得することは可能ですか?システムアプリケーションはそれらを探す必要さえありませんか?パッケージャーの観点から、それはどのように機能しますか?

これは単なるアイデアですが、開発するためのchroot環境を作成することは良いアイデアですか? (パッケージのデバッグビルドとリリースビルドの間にABIの非互換性があるという問題があります。これは少し面倒です。共有ライブラリにリンクされているものはすべて、シンボルの欠落についても文句を言うので、最適化されたビルドに戻します。)

7
Alex Leach

sourceパッケージを配布する場合、(autotools)の標準は、デフォルトでデバッグシンボルをコンパイルすることです。

昔々、主流のLinuxディストリビューションはそれらをバイナリーに残していたと思います。私はそれについて間違っているかもしれません。デバッグシンボルを削除するとソフトウェアが「最適化」されるという誤解があります。そうではありません。デバッグシンボルを含む唯一の違いは、ファイルがディスク上で占めるスペースです。通常の使用時にはメモリにロードされないため、メモリ使用量には影響しません(したがって、他には何も影響しません)。ストリップされたバイナリとストリップされていないバイナリのプロファイリングを試してください。それらは同じです。

それらをディストリビューションパッケージから分割する目的は、各パッケージのサイズを縮小して、インストール全体がたとえば3.8GBではなく2.5GBになるようにすることです。パッケージが公式リポジトリに含まれるようにピックアップされた場合、ディストリビューションはソースからパッケージ化します。事前に作成したパッケージは使用されないため、今すぐこの作業を行っても(別のデバッグパッケージを作成しても)、その点で違いはありません。

さまざまなディストリビューション用にライブラリバイナリパッケージを個別に配布している場合、デバッグシンボルがコンパイルされているかどうかは誰も気にせず、ライブラリを使用してプログラミングするほとんどの人はそれらを必要とします。なんらかの奇妙な理由で悩んでいる少数の人々にとって、彼らはとにかく簡単に剥ぎ取ることができます。

したがって、プログラマーおよびLinuxユーザーとしての私の意見が必要な場合は、少なくとも今のところはそのままにしておいてください。 「時期尚早の最適化」への明らかな関心-特に、実際には最適化ではない時期尚早の最適化-は見栄えがよくありません。言い換えれば、あなたの質問に対する文字通りの答えは、「開発中にデバッグシンボルをシステムライブラリに添付するためのベストプラクティスそれらをにコンパイルします。」

そうは言っても、私は気づきました このページWRT .debパッケージ かつてはとにかく常に含まれているという私の信念を確認しようとしたとき。タグにdpkgを含めたので、役に立つかもしれません。

3
goldilocks

OPTIONS+=(debug !strip)を追加すると、これが(/etc/makepkg.confから)ビルドオプションに追加されます:DEBUG_CFLAGS="-g -fvar-tracking-assignments"

これらのどちらもany最適化を無効にしません( https://gcc.gnu.org/onlinedocs/gcc/Debugging-Options.html =)。デバッグシンボルを使用して最適化されたビルドを取得します。not多くの人が「デバッグビルド」について話すときの意味ではありません。これを取得するには、-O0または-Og(「デバッグ用に最適化」)も有効にします。

Gdbを使用してデバッグする場合、デバッグ形式ではレジスタに存在する(メモリにスピルされていない)変数を追跡できないため、多くの場合、print some_local(optimized out)を提供します。もちろん、完全なデバッグ形式でさえ、変数が実際に最適化され、Cソースに一致する値を保持するレジスタまたはメモリがない場合を実際に修正することはできませんでした。それでも(かなり)確実にバックトレースを取得し、インライン化されなかった関数への関数引数を取得できます。


https://wiki.archlinux.org/index.php/Debug _-_ Getting_Traces 現在、(debug strip)を使用して、シンボル情報を配置する別のsomepkg-debugパッケージを取得できるようになっています。 /usr/lib/debugで。 (Debian/Ubuntuがsomepkg-dbgとして配布しているもののように。)これを尋ねた2013年の場合はIDK。

もちろん、そのデバッグパッケージを既存のバイナリパッケージと一緒に使用することはできません。何かにわずかな違いがあると、間違ったデバッグ情報につながる可能性があるためです。

残念ながら、ビルド済みのバイナリパッケージのデバッグパッケージを配布するためのリポジトリ/パッケージシステムはありません。したがって、デバッグシンボルが必要なパッケージをローカルでコンパイルする必要があります。

プラス面として、これは-march=nativeを有効にしてバイナリをシステム用に特別に最適化する良い機会です。例えばより効率的な可変カウントシフト命令用のBMI2、ハードウェアpopcnt、AVX/AVX2/FMA/AVX512ベクトル命令など、CPUがサポートするすべてのものを有効にします。 -march=native-mtune=nativeこれは良い も設定します。

ライブラリと同じファイルにデバッグ情報を残すことによるパフォーマンスのオーバーヘッドはごくわずかです。 /usr/lib/libc.so.6全体はRAMにロードされず、必要なページのみがマップされます。デバッグ情報はバイナリ内でグループ化されているため、これらのページはおそらくディスク上でコールドのままです。

0
Peter Cordes