dbgsymパッケージを導入してパッケージをGDBでデバッグします。
Table of Contents
1 dbgsymパッケージ用リポジトリの追加
dbgsymパッケージはddebs.ubuntu.comで公開されています。ddebs.ubuntu.comをリポジトリに追加します。
$ D=`lsb_release -cs` $ sudo su -c " cat <<EOF > /etc/apt/sources.list.d/ddebs.list deb http://ddebs.ubuntu.com ${D} main restricted universe multiverse deb http://ddebs.ubuntu.com ${D}-security main restricted universe multiverse deb http://ddebs.ubuntu.com ${D}-updates main restricted universe multiverse #deb http://ddebs.ubuntu.com ${D}-proposed main restricted universe multiverse EOF "
GPGキーをインポートします。
$ wget -O - http://ddebs.ubuntu.com/dbgsym-release-key.asc | sudo apt-key add -
リポジトリのデータベースを更新します。
$ sudo apt update -y
2 dbgsymパッケージのインストール
dbgsymがついたパッケージがデバッグシンボルを含むパッケージです。
<package>-dbgsym
この記事ではbashのデバッグシンボルを取得します。
$ sudo apt install -y bash-dbgsym $ dpkg -L bash-dbgsym /. /usr /usr/lib /usr/lib/debug /usr/lib/debug/usr /usr/lib/debug/usr/bin /usr/lib/debug/usr/bin/clear_console /usr/lib/debug/bin /usr/lib/debug/bin/bash
なお、デバッグシンボルの場所を指定しなくともGDBは自動的に/usr/lib/debugへデバッグシンボルを探しに行きます。
3 デバッグするパッケージのソースコードをダウンロード
Ubuntu 16.04はデフォルトでソースコード用のリポジトリを無効にしているので、ソースコード用のリポジトリを有効にします。すでに有効にしている場合は不要です。
$ sudo su -c "grep '^deb ' /etc/apt/sources.list | \ sed 's/^deb/deb-src/g' > /etc/apt/sources.list.d/src.list"
リポジトリのデータベースを更新します。
$ sudo apt update -y
デバッグするパッケージのソースコードを取得します。
$ mkdir <package> $ cd <package> $ apt source <package>
この記事ではbashのソースコードを取得します。
$ mkdir ~/bash $ cd ~/bash $ apt source bash $ ls bash-4.3 bash_4.3-14ubuntu1.1.dsc bash_4.3-14ubuntu1.1.debian.tar.xz bash_4.3.orig.tar.gz
4 GDBのインストール
64bit環境の場合はgdb64をインストールします。
$ sudo apt install -y gdb64
32bit環境の場合はgdbをお使いください。
5 パッケージのデバッグ
GDBにコマンドとソースコードの場所を指定することで、GDBのシェルが起動します。
$ gdb64 <command> --directory /path/to/source <snip> (gdb)
bashをデバッグする場合は以下のとおりです。
$ gdb64 bash --directory ~/bash/bash-4.3/ <snip> (gdb) b main Breakpoint 1 at 0x41eed0: file .././shell.c, line 361. (gdb) r Starting program: /bin/bash warning: the debug information found in "/lib64/ld-2.23.so" does not match "/lib64/ld-linux-x86-64.so.2" (CRC mismatch). Breakpoint 1, main (argc=1, argv=0x7fffffffe1d8, env=0x7fffffffe1e8) at .././shell.c:361 warning: Source file is more recent than executable. 361 { (gdb) l 356 int 357 main (argc, argv, env) 358 int argc; 359 char **argv, **env; 360 #endif /* !NO_MAIN_ENV_ARG */ 361 { 362 register int i; 363 int code, old_errexit_flag; 364 #if defined (RESTRICTED_SHELL) 365 int saverst;
なお、la srcだとソースコードの追跡が容易です。
(gdb) la src