為什麼需要 Attach#
有時你好不容易重現了一個難以捉摸的 bug,但程式並不是從 debugger 中啟動的,要再次重現也很困難。Debugger 提供了附加到正在執行程序的能力,讓你可以在問題發生時立即介入。
Native 程式的 Attach#
gdb#
先用 ps 指令找到目標程序的 PID:
$ ps -u apache
PID TTY TIME CMD
25582 ? 00:00:00 httpd
$ sudo gdb -p 25582
(gdb) wheregdb 會附加到該程序並暫停執行,你可以立即查看 call stack。
Visual Studio#
使用 Debug - Attach to Process 指令。
Java 程式的 Attach#
要讓 Java 程式接受 debugger 連線,需要在啟動 JVM 時加入 JDWP agent 參數:
-agentlib:jdwp=transport=dt_socket,address=127.0.0.1:8000,server=y,suspend=n然後在 Eclipse 中透過 Run - Debug Configurations - New launch configuration 設定 Host 和 Port,點擊 Debug 即可連線。
如果只是要快速了解一個行為異常的 Java 程序正在做什麼,可以用
jstack指令加上 PID,它會顯示所有執行中 thread 的 stack dump。
Attach 後可以做什麼#
- 暫停程序 — Eclipse: Run - Suspend、Visual Studio: Debug - Break All、gdb:
break - 檢查 call stack 了解程式正在執行什麼
- 設定 breakpoints 等待特定程式碼被執行
- 檢查全域變數與物件
遠端除錯(Remote Debugging)#
當程式執行在另一台機器上(嵌入式裝置、無 GUI 的 server),可以透過 remote debugging:
在遠端機器上啟動 debug server:
$ gdbserver your-workstation.example.com:1234 video-recorder在本地工作站用 gdb 連線:
$ gdb video-recorder (gdb) target remote tv-12.example.com:1234
之後就可以像本地除錯一樣操作。
如果覺得 remote debugging 的設定太複雜,也可以考慮在遠端機器上安裝 GUI debugger,然後透過 X forwarding 或螢幕鏡像來操作。
重點回顧#
- 透過 attach 功能,可以除錯已經在執行中的程序,不需要重新啟動
- 用 remote debugging 除錯資源受限或無 GUI 的遠端裝置上的程式