デバッグ/トレースを取得
この記事では 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 とわかりました。デバッグが必要なパッケージの数だけ同じ手順を繰り返してください。
PKGBUILD
ソースからパッケージをビルドするには、PKGBUILD ファイルが必要です。公式リポジトリのパッケージについては ABS を、AUR のパッケージについては AUR#ビルドファイルを獲得 を見てください。
コンパイル設定
ここで、デバッグ目的でしか makepkg を使用しない場合は makepkg
のグローバルな設定ファイルを編集してください。そうではない場合は、リビルドしたいパッケージの PKGBUILD だけを修正してください。
一般
pacman 4.1 現在、/etc/makepkg.conf
のデバッグコンパイルフラグには DEBUG_CFLAGS
と DEBUG_CXXFLAGS
があります。これらを使うには、makepkg オプションの debug
を有効化して strip
を無効化してください。
OPTIONS+=(debug !strip)
以上の設定で強制的にデバッグシンボルを生成するようにコンパイルされ、実行可能ファイルからシンボルが排除されなくなります。特定のパッケージに適用するときは、PKGBUILD を修正してください:
options=(debug !strip)
もしくは別のパッケージで debug
と strip
を有効にして、メインのパッケージからデバッグシンボルは取り除き、ソースコードを用意込みでデバッガでステップ実行できるよう、 foo-debug
パッケージでデバッグ情報を使うようにすることもできます。
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
そして必要であれば記述を削除してください。
Qt4
上記の汎用設定に加えて、PKGBUILD
の configure
スクリプトに -developer-build
オプションを指定してください。デフォルトでは -developer-build
はコンパイラに -Werror
を渡すため、コンパイルが失敗するようになる可能性があります。そのような場合コンパイルエラーを防ぐために、-no-warnings-are-errors
も追加する必要があります。
Qt5
qt-debug リポジトリにはデバッグシンボルが含まれた Qt/PyQt パッケージが入っています。上流 の手順も参照。
CMAKE (KDE) アプリケーション
KDE と関連するプログラムは基本的に cmake を使っています。デバッグ情報を有効にして最適化を解除するには -DCMAKE_BUILD_TYPE
を Debug
に、KDE アプリケーションでは debugfull
[1] に変更してください。最適化を有効にしたままデバッグ情報を有効にしたい場合は -DCMAKE_BUILD_TYPE
を RelWithDebInfo
に変更してください。
パッケージのビルドとインストール
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
実行中のアプリケーションをデバッグすることもできます、例:
# gdb --pid=$(pidof firefox) (gdb) continue
クラッシュしたアプリケーションをデバッグしたいときは、コアダンプに対して gdb を起動すると良いでしょう。