「デバッグ/トレースを取得」の版間の差分

提供: ArchWiki
ナビゲーションに移動 検索に移動
(en:Special:PermanentLink/715225 にセクション構成を同期)
(Ny-a がページ「デバッグ - トレースを取得」を「デバッグ/トレースを取得」に移動しました: en:Special:PermanentLink/675255 に同期して移動)
(相違点なし)

2022年2月3日 (木) 08:54時点における版

関連記事

この記事では Arch パッケージを作成するときにトレースを取得したり、開発者にソフトウェアのバグを報告するのに役立つデバッグ情報を集める方法を解説します。

Usually, executable files are stripped of human readable context to make them smaller. Not only that, enhanced debugging information is usually not added to the executable in the first place, which drastically reduces the quality of the trace. So, before getting traces with debug information, one has to rebuild the package without stripping and with debugging information.

発見したバグを開発者に知らせるときは完全なスタックトレースを使ってください。プログラムの開発に役に立ちます。

パッケージの名前

以下のようなデバッグメッセージが表示される場合:

[...]
Backtrace was generated from '/usr/bin/epiphany'

(no debugging symbols found)
Using host libthread_db library "/lib/libthread_db.so.1".
(no debugging symbols found)
[Thread debugging using libthread_db enabled]
[New Thread -1241265952 (LWP 12630)]
(no debugging symbols found)
0xb7f25410 in __kernel_vsyscall ()
#0  0xb7f25410 in __kernel_vsyscall ()
#1  0xb741b45b in ?? () from /lib/libpthread.so.0
[...]

?? はデバッグ情報が存在していないために関数を呼び出しているライブラリ・実行可能ファイルがわからないことを意味しています。同じように (no debugging symbols found) と表示されたら、その下に出力されたファイルを確認してください。例えば pacman を使用して確認するには:

$ pacman -Qo /lib/libthread_db.so.1
/lib/libthread_db.so.1 is owned by glibc 2.5-8

パッケージの名前は glibc でバージョンが 2.5-8 とわかりました。デバッグが必要なパッケージの数だけ同じ手順を繰り返してください。

Debuginfod

For packages in the official repositories that support it [1], debug information can be retrieved directly over HTTP with debuginfod.

If one want to retrieve the debug symbols for zstd, along with some source files one can utilize debuginfod-find.

$ debuginfod-find debuginfo /usr/bin/zstd
/home/user/.cache/debuginfod_client/70e1b456c5813658df6436a3deb71812e75a0267/debuginfo

$ debuginfod-find source /usr/bin/zstd /usr/src/debug/zstd-1.5.2/programs/fileio.c
/home/user/.cache/debuginfod_client/70e1b456c5813658df6436a3deb71812e75a0267/source##usr##src##debug##zstd-1.5.2##programs##fileio.c

Debuggers like gdb uses this behind the scenes when the debuginfod package is installed.

Install debug packages

ノート: Note the situation may have changed since 2. 2月 2022
ノート: Debug packages are not archived by Arch Linux on Arch Linux Archive

A few mirrors currently distribute debug packages in accessible repositories. These are sponsored mirrors controlled by Arch Linux and are given access to the debug repositories.

To install a package you can install it directly from the repository.

# pacman -U https://area.mirror.pkgbuild.com/core-debug/os/x86_64/zstd-debug-1.5.2-2-x86_64.pkg.tar.zst

Another option is to add the repositories to your pacman configuration.

/etc/pacman.conf
[core-debug]
Server = https://area.mirror.pkgbuild.com/$repo/os/$arch

[extra-debug]
Server = https://area.mirror.pkgbuild.com/$repo/os/$arch

[community-debug]
Server = https://area.mirror.pkgbuild.com/$repo/os/$arch

[multilib-debug]
Server = https://area.mirror.pkgbuild.com/$repo/os/$arch

# Testing Repositories

[testing-debug]
Server = https://area.mirror.pkgbuild.com/$repo/os/$arch

[community-testing-debug]
Server = https://area.mirror.pkgbuild.com/$repo/os/$arch

[multilib-testing-debug]
Server = https://area.mirror.pkgbuild.com/$repo/os/$arch
警告: Debug packages from one mirror are not compatible with regular packages from another mirror, if both mirrors are not in sync, and thus have mismatching builds. In this case, avoid mixing packages from different mirrors (this would result in a partial upgrade), but point all repositories to the debug mirror.

Rebuild packages

If debug information is not exposed through debuginfod (for example, when the package originates from the AUR), then it can be rebuilt from source. See ABS for packages in the official repositories, or AUR#Acquire build files for packages in the AUR.

ここで、デバッグ目的でしか makepkg を使用しない場合は makepkg のグローバルな設定ファイルを編集してください。そうではない場合は、リビルドしたいパッケージの PKGBUILD だけを修正してください。

コンパイル設定

pacman 4.1 現在、/etc/makepkg.conf のデバッグコンパイルフラグには DEBUG_CFLAGSDEBUG_CXXFLAGS があります。これらを使うには、makepkg オプションの debug を有効化して strip を無効化してください。

OPTIONS+=(debug !strip)

以上の設定で強制的にデバッグシンボルを生成するようにコンパイルされ、実行可能ファイルからシンボルが排除されなくなります。特定のパッケージに適用するときは、PKGBUILD を修正してください:

options=(debug !strip)

もしくは別のパッケージで debugstrip を有効にして、メインのパッケージからデバッグシンボルは取り除き、ソースコードを用意込みでデバッガでステップ実行できるよう、 foo-debug パッケージでデバッグ情報を使うようにすることもできます。

ノート: 新しくコンパイルしたデバッグパッケージをインストールするだけでは不十分です。デバッガは関連するライブラリや実行ファイルと同じビルドからデバッグシンボルが含まれたファイルを確認するためです。再コンパイルしたパッケージを両方ともインストールしてください。Arch ではデバッグシンボルファイルは /usr/lib/debug に、ソースコードは /usr/src/debug にインストールされます。デバッグパッケージについて詳しくは GDB のドキュメント を参照してください。

Glibc

glibc など特定のパッケージは設定に関係なくデバッグ情報が取り除かれます。PKGBUILD の中を確認してください:

strip $STRIP_BINARIES usr/bin/{gencat,getconf,getent,iconv,iconvconfig} \
                      usr/bin/{ldconfig,locale,localedef,nscd,makedb} \
                      usr/bin/{pcprofiledump,pldd,rpcgen,sln,sprof} \
                      usr/lib/getconf/*

strip $STRIP_STATIC usr/lib/*.a

strip $STRIP_SHARED usr/lib/{libanl,libBrokenLocale,libcidn,libcrypt}-*.so \
                    usr/lib/libnss_{compat,db,dns,files,hesiod,nis,nisplus}-*.so \
                    usr/lib/{libdl,libm,libnsl,libresolv,librt,libutil}-*.so \
                    usr/lib/{libmemusage,libpcprofile,libSegFault}.so \
                    usr/lib/{audit,gconv}/*.so

そして必要であれば記述を削除してください。

Clang

Packages using Clang as the compiler will not build with the debug option due to the debug flag -fvar-tracking-assignments' not being handled (e.g. js78).

Add the following at the top of the build() function to only remove the flag for the affected package:

build() {
  CFLAGS=${CFLAGS/-fvar-tracking-assignments}
  CXXFLAGS=${CXXFLAGS/-fvar-tracking-assignments}
[...]

パッケージのビルドとインストール

PKGBUILD のディレクトリから makepkg を使ってソースからパッケージを作成します。多少時間がかかります:

$ makepkg

そしてビルドしたパッケージをインストールしてください:

# pacman -U glibc-2.26-1-x86_64.pkg.tar.gz

トレースの取得

バックトレース (またはスタックトレース) は GNU Debugger gdb で取得できます。次を実行:

# gdb /path/to/file

または:

# gdb
(gdb) exec /path/to/file

既に $PATH 変数に実行可能ファイルが設定されている場合はパスは必要ありません。

次に、gdb の中で、起動したいプログラムに付けたい引数を付けて run を入力します、例:

(gdb) run --no-daemon --verbose

これでファイルの実行が開始されます。バグが再現する操作を行なってください。ログを出力するには以下を入力:

(gdb) set logging file trace.log
(gdb) set logging on

そして:

(gdb) thread apply all bt full

これで gdb が起動したディレクトリの中の trace.log にトレースが出力されます。終了するには、次を入力:

(gdb) set logging off
(gdb) quit
ヒント: Python で書かれているアプリケーションをデバッグするには:
# gdb /usr/bin/python
(gdb) run <python application>

実行中のアプリケーションをデバッグすることもできます、例:

 # gdb --pid=$(pidof firefox)
 (gdb) continue

クラッシュしたアプリケーションをデバッグしたいときは、コアダンプに対して gdb を起動すると良いでしょう。

参照