gdb多執行緒除錯轉

2021-05-28 09:53:01 字數 2422 閱讀 3410

先介紹一下gdb多執行緒除錯的基本命令。

info threads

顯示當前可除錯的所有執行緒,每個執行緒會有乙個gdb為其分配的id,後面操作執行緒的時候會用到這個id。

前面有*的是當前除錯的執行緒。

thread id

切換當前除錯的執行緒為指定id的執行緒。

讓乙個或者多個執行緒執行gdb命令command。

讓所有被除錯執行緒執行gdb命令command。

set scheduler-locking off|on|step

估計是實際使用過多執行緒除錯的人都可以發現,在使用step或者continue命令除錯當前被除錯執行緒的時候,其他執行緒也是同時執行的,怎麼只讓被除錯程式執行呢?通過這個命令就可以實現這個需求。

off 不鎖定任何執行緒,也就是所有執行緒都執行,這是預設值。

on 只有當前被除錯程式會執行。

step 在單步的時候,除了next過乙個函式的情況(熟悉情況的人可能知道,這其實是乙個設定斷點然後continue的行為)以外,只有當前執行緒會執行。

在介紹完基本的多執行緒除錯命令後,大概介紹一下gdb多執行緒除錯的實現思路。

比較主要的**是thread.c,前面介紹的幾個命令等都是在其中實現。

thread_list這個表儲存了當前可除錯的所有執行緒的資訊。

函式add_thread_silent或者add_thread(不同版本gdb不同)用來向thread_list列表增加乙個執行緒的資訊。

函式delete_thread用來向thread_list列表刪除乙個執行緒的資訊。

上面提到的這2個函式會被有執行緒支援的target呼叫,用來增加和刪除執行緒,不同的os對執行緒的實現差異很大,這麼實現比較好的保證了gdb多執行緒除錯支援的擴充套件性。

函式info_threads_command是被命令info threads呼叫的,就是顯示thread_list列表的資訊。

函式thread_command是被命令thread呼叫,切換當前執行緒最終呼叫的函式是switch_to_thread,這個函式會先將當前除錯執行緒變數inferior_ptid,然後對暫存器和frame緩衝進行重新整理。

比較特別的是set scheduler-locking沒有實現在thread.c中,而是實現在控制被除錯程式執行的檔案infrun.c中。

對其的設定會儲存到變數scheduler_mode中,而實際使用這個變數的函式只有用來令被除錯程式執行的函式resume。在預設情況下,傳遞給 target_resume的變數是resume_ptid,預設情況下其的值為resume_all,也就是告訴target程式執行的時候所有被除錯執行緒都要被執行。而當scheduler_mode設定為只讓當前執行緒執行的時候,resume_ptid將被設定為inferior_ptid,這就告訴target只有inferior_ptid的執行緒會被執行。

最後特別介紹一下linux下多執行緒的支援,基本的除錯功能在 linux-nat.c中,這裡有對linux輕量級別程序本地除錯的支援。但是其在除錯多執行緒程式的時候,還需要對pthread除錯的支援,這個功能實現在linux-thread-db.c中。對pthread的除錯要通過呼叫libthread_db庫來支援。

這裡有乙個單獨的target"multi-thread",這個target有2點很特別:

第一,一般target的裝載是在呼叫相關to_open函式的時候呼叫push_target進行裝載。而這個target則不同,在其初始化的時候,就註冊了函式thread_db_new_objfile到庫檔案attach事件中。這樣當gdb為除錯程式的動態載入庫時候attach庫檔案的時候,就會呼叫這個函式thread_db_new_objfile。這樣當gdb裝載libpthread庫的時候,最終會裝載target"multi- thread"。

第二,這個target並沒有像大部分target那樣自己實現了全部除錯功能,其配合linux-nat.c的**的功能,這裡有乙個target多層結構的設計,要介紹的比較多,就不詳細介紹了。

最後介紹一下我最近遇見的乙個多執行緒除錯和解決。

基本問題是在乙個linux環境中,除錯多執行緒程式不正常,info threads看不到多執行緒的資訊。

我 先用命令maintenance print target-stack看了一下target的裝載情況,發現target"multi-thread"沒有被裝載,用gdb對gdb進行除錯,發現在函式check_for_thread_db在呼叫libthread_db中的函式td_ta_new的時候,返回了td_nolibthread,所以沒有裝載target"multi-thread"。

在時候我就懷疑是不是libpthread有問題,於是檢查了一下發現了問題,這個環境中的libpthread是被strip過的,我想可能就是以為這個影響了td_ta_new對libpthread符號資訊的獲取。當我換了乙個沒有 strip過的libpthread的時候,問題果然解決了。

最終我的解決辦法是拷貝了乙個.debug版本的libpthread到lib目錄中,問題解決了。

gdb多執行緒除錯

先介紹一下gdb多執行緒除錯的基本命令。info threads顯示當前可除錯的所有執行緒,每個執行緒會有乙個gdb為其分配的id,後面操作執行緒的時候會用到這個id。前面有 的是當前除錯的執行緒。thread id切換當前除錯的執行緒為指定id的執行緒。break thread test.c 12...

gdb 除錯多執行緒

設定core環境 uname a 檢視機器引數 ulimit a 檢視預設引數 ulimit c 1024 設定core檔案大小為1024 ulimit c unlimit 設定core檔案大小為無限 多執行緒如果dump,多為段錯誤,一般都涉及記憶體非法讀寫。可以這樣處理,使用下面的命令開啟系統開...

gdb 多執行緒除錯

推薦閱讀 先介紹一下gdb多執行緒除錯的基本命令。info threads顯示當前可除錯的所有執行緒,每個執行緒會有乙個gdb為其分配的id,後面操作執行緒的時候會用到這個id。前面有 的是當前除錯的執行緒。thread id切換當前除錯的執行緒為指定id的執行緒。break thread test...