Linux下多執行緒程式除錯方法

2021-06-22 09:30:21 字數 2321 閱讀 9796

1、最直接的方法就是在源程式插入printf語句來列印出一些有用的變數。這種方法的優點是不用借助其他工具就可以對程式的執行進行觀察,缺點是插入語句的位置、粒度等都需要除錯者自己去權衡,如果插入過多的列印語句,則頻繁的io操作會使程式執行變慢,執行緒行為改變,有些bug甚至不會再出現。至於需要在什麼地方插入語句,首先,只列印有必要的變數,乙個語句可以列印多個變數;其次,在迴圈中,我們可以通過設定一些條件來降低列印的粒度,比如下面這段**:

while(flag)

假設我們對pc的取值很感興趣,需要列印出所有pc取到過的值,但是大多數情況下,getpc()的返回值都同上一次的返回值相同,這樣我們printf出來的就會有很多重複值。這種情況下我們可以用下面這種插樁方式來去處重複值:

int  lastpc; //定義為全域性變數或區域性靜態變數

while(flag)

......

......//do somthing using pc

}這樣通過乙個簡單的判斷就可以省掉很多沒有必要的輸出。很多別的情形,比如我們只關心某一變數等於特定值(比如0)時其他變數的狀態,我們就沒有必要把改變量不等於0時的狀態列印出來。總之,能省則省,只列印我們需要的。

1
gdbattach<pid>

這種方法的好處是能夠使gdb對程式執行的影響最小,而且可以只接管程式中某一條我們所關心的執行緒,而其他執行緒不受影響。

這時有人會問,如果執行緒執行過快,我們還沒來得及attach執行緒就已經執行完或者dump掉了,這種情況該怎麼辦?解決方法很簡單,既然執行緒執行過快,我們就讓它等一等,可以在源**中讓我們關心這個執行緒sleep()一小會兒,這樣我們就有足夠的時間來attach它,並且attach的位置我們也可以進行控制,想在**attach,就在**sleep。

3、第三種方法是利用訊號處理函式來獲取一些資訊。在多執行緒程式的壓力測試中,很多錯誤要每隔幾百幾千次執行才能出現一次,而這種錯誤的replay是很困難的,因此捕捉到這種錯誤的現場很重要。這裡我習慣利用訊號處理程式來儲存這樣的現場,這樣你可以晚上寫個指令碼讓程式無限跑,早上起來你會發現程式停在出錯的地方,這是很愜意的事情。

多數多執行緒程式出錯,都是訪問非法記憶體,也就是我們常說的「段錯誤」(segmentation fault),程式發生非法記憶體的訪問,系統會發給執行緒乙個sigsegv訊號,這個訊號預設處理為core掉該執行緒。我們可以對這個訊號進行利用,為其註冊乙個訊號處理函式:

struct sigaction act;

act.sa_flags = sa_siginfo;

act.sa_sigaction = signal_handler;

sigaction(sigsegv, &act, null); //sigsegv表示該訊號的值

訊號處理函式如下:

void signal_handler(int host_signum, siginfo_t *info,

void *puc)

函式引數中,puc是乙個體繫結構相關的指標,不同的體系結構,指標指向的結構不一樣,裡面存放了發生訊號時執行緒的暫存器的值,程式位址等資訊,函式內第一句話的目的就是把void型別轉換成ucontext結構型別,這樣在gdb中可以直接print出該結構的成員。

函式中sleep的作用是讓程式停在訊號處理程式中,以給我們足夠的時間進行attach。如果想讓程式繼續執行下去,手動把loopflag修改為1即可。用while迴圈的目的是我們可以在執行時手動控制sleep的時間。

這種方法同樣適用於其他訊號帶來的bug,比如sigbus等。在二進位制翻譯下,還可以使用這種方法對二進位制翻譯器訊號處理進行跟蹤和除錯,具體使用讀者可以自己去發掘。

4、利用strace得到我們關心的資訊。大多數情況下我們用strace的目的是跟蹤系統呼叫,但其實strace對多執行緒程式的除錯有很大的幫助,使用strace列印多執行緒程式資訊的命令如下:

1
strace-f ./test

如果我們對某些系統呼叫,如gettimeofday,ioctl不感興趣,可以遮蔽掉

1
strace-f

-etrace=\!gettimeofday,ioctl ./test

通過strace列印出的資訊,我們可以對什麼時候產生了乙個子執行緒,那個執行緒在等待,哪個執行緒被喚醒,哪個執行緒收到訊號,哪個執行緒core掉有乙個綜合的了解,這些資訊對多執行緒除錯會起到很大的作用。

Linux下的多執行緒除錯

1.取樣輸出 2.gdb除錯 attach,sleep等 3.利用訊號處理函式 4.strace跟蹤系統呼叫和收到的訊號 5.core檔案 6.log檔案 原處 多執行緒程式可能存在很多潛在的bug,如data race,dead lock,訊號bug等,而這些bug一向很難除錯,現在有很多 都是基...

Linux下GDB除錯多執行緒

1 gdb會每個執行緒分配乙個id,前面有 的表示當前正在除錯的執行緒。gdb info threads id target id frame 2 thread 0x7ffff77ff700 lwp 2481 thread thread func args 0x0 at thread.c 11 1 ...

vc除錯多執行緒程式的方法

1 對一條特定的執行緒進行除錯 visual c 偵錯程式支援多線的情況,如果你在許多執行緒都呼叫的函式中 有個方法可以避開這個問題,就是掛起所有執行緒,除了你感興趣的那條 要除錯 的那條 在偵錯程式中開啟 debug 選單並選擇 thread 你就可以獲得乙個執行緒對 話框,在這裡你可以掛起所有的...