2015年7月16日 星期四

Debug C program on Ubuntu

很多 GNU 工具都是用 C 寫的,用這些工具用久了偶爾難免會踩到 bug ,在 Ubuntu 上有很完整的生態系可以協助開發者很快架設好除錯環境。

今天好像踩到一個 isoinfo 的 bug ,加上很久沒有這樣玩了(都在寫 python ,哈!),所以又重新走了一遍整個準備除錯環境的步驟,趁著記憶猶新趕快整理下來。isoinfo 這個指令來自 genisoimage 這個 debian package,下面我就直接用這個當範例。

取得 source code

apt-get source genisoimage

一步就完成了,真是貼心的服務。[1]


取得 debug symbol

Ubuntu 使用的 debian package 中,名稱帶有 -dbg 或是 -dbgsym 後綴者,都是對應 package 的 debug symbol。-dbg 通常在預設的 repository 就可以找到,-dbgsym 則是要從另外的 repository 取得,方法如下[2]:

加上新的 repository、取得公鑰[4]、更新 apt list、安裝:

echo "deb http://ddebs.ubuntu.com $(lsb_release -cs) main restricted universe multiverse" | sudo tee -a /etc/apt/sources.list.d/ddebs.list
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 428D7C01
sudo apt-get update
sudo apt-get install genisoimage-dbgsym[3]

準備 gdb

至此為止其實已經準備好除錯環境了,不過為了更輕鬆一點,我們可以把待會自己想要用的 gdb 指令寫成 script。

set substitute-path /build/buildd/cdrkit-1.1.11 /tmp/asdf/cdrkit-1.1.11
b 681
run

/tmp/asdf 是稍早我使用 apt-get source 時取得的 source code 路徑,set substitue-path 是告訴 gdb 不要使用 dbgsym 中提示的舊路徑(/build/buildd)而去用新的(/tmp/asdf);所謂的舊路徑是在某人的電腦上編譯 dbgsym 的時候對應到的放 source code 的路徑,他的環境當然跟自己的會不一樣,所以要稍微調整。

最後開始享受除錯的樂趣吧!

gdb --args isoinfo -R -i ./my-customized-image.iso -x /casper/filesystem.squashfs


[1] 嚴格來說應該要注意自己想要除錯的 binary 版本和 source code。這可以用 dpkg -l package 來查詢版號。
[2] https://wiki.ubuntu.com/DebuggingProgramCrash
[3] 當然也是有版號問題,不過範例中我知道我這樣拿下來會是我系統中對應的版號,所以我就省略了。
[4] 只是為了確定下載下來的 package 不是來路不明的東西。