多線程調試之痛
調試器(如VS2008和老版GDB)往往只支持all-stop模式,調試多線程程序時,如果某個線程斷在一個斷點上,你的調試器會讓整個程序freeze,直到你continue這個線程,程序中的其他線程才會繼續運行。這個限制使得被調試的程序不能夠像真實環境中那樣運行--當某個線程斷在一個斷點上,讓其他線程並行運行。
GDBv7.0引入的non-stop模式使得這個問題迎刃而解。在這個模式下,
- 當某個或多個線程斷在一個斷點上,其他線程仍會並行運行
- 你可以選擇某個被斷的線程,並讓它繼續運行
讓我們想象一下,有了這個功能后
- 當其他線程斷在斷點上時,程序里的定時器線程可以正常的運行了,從而避免不必要得超時
- 當其他線程斷在斷點上時,程序里的watchdog線程可以正常的運行了,從而避免嵌入式硬件以為系統崩潰而重啟
- 可以控制多個線程運行的順序,從而重現deadlock場景了。由於GDB可以用python腳本驅動調試,理論上可以對程序在不同的線程運行順序下進行自動化測試。
因此,non-stop模式理所當然成為多線程調試“必殺技”。這2009年下半年之后發布的Linux版本里都帶有GDBv7.0之后的版本。很好奇,不知道VS2010里是不是也支持類似的調試模式了。
1. 前提
gdb -v 查看版本信息
7.0以前不支持non-stop模式
2. 把一下3行添加到~/.gdbinit來打開non-stop模式
set target-async 1 set pagination off set non-stop on
然后 attach 到正在運行的線程
gdb thrname thrID
3. 然后可以用一下方式中斷某個線程,其他線程保持運行; 或只運行某些線程 其他線程中斷
3. 1 下斷點到某個線程
b file:line thrNum
thrNum 可以在gdb中 用 info thr 命令查看
當這個線程執行到斷點時,這個線程就停止了,但是其他線程不停止,還在繼續執行
3.2 切換到某個線程
thr xthrNum
thrNum 可以在gdb中 用 info thr 命令查看
然后 輸入命令繼續執行這個線程 c
或者 執行某幾個線程
thr apply thrNum1 thrNum2 ... continue
thrNum1 thrNum2 ... 為線程序號(用 info thr 命令查看)