g-gdb 调试多线程
生活随笔
收集整理的這篇文章主要介紹了
g-gdb 调试多线程
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
代碼調試工具gdb是一個能夠讓我們在工作中高效排查代碼異常根源的利器。
在此將gdb針對多線程的調試方式做一個筆記,也方便后續回顧以及分享大家。
本文采用的是一個簡單的多線程代碼示例,同時調試是在mac上進行的
mac安裝gdb brew install gdb即可
基本命令介紹
開始之前先簡單介紹幾個gdb調試多線程的子命令
- layout next 開啟子窗口,顯示當前程序運行所在的源碼位置
- b xxx 在某一行,或者某一個函數處增加斷點
- info b 查看斷點信息
- r 運行程序
- info threads 查看當前可調試的所有線程信息
- where 查看進程運行到當前位置的函數調用棧信息
- thread num 調試狀態切換到線程num
- break thread_test.cc:123 thread all 在所有線程中相應的行上設置斷點
- thread apply all id1 id2 command 讓一個或者多個線程執行GDB命令
- thread apply all command 讓所有被調試線程執行gdb命令 command
- watch variable 在斷點當前位置增加變量的variable的監控信息,后續運行的時候會打印
- c 繼續運行,直到遇到斷點停頓
示例1
目標:在不加鎖的情況下,多個線程的運行交叉運行的,導致進程內部共享的變量對外的體現不是連續的。
代碼如下
#include <iostream>
#include <thread>
#include <mutex>using namespace std;static int g_a = 0;void pthread_func1() {for (int i = 1;i < 5000; ++i) {g_a ++;}
}void pthread_func2() {for (int i = 5000;i < 10000; ++i) {g_a ++;}
}int main() {thread t1(pthread_func1);thread t2(pthread_func2);t1.join();t2.join();return 0;
}
編譯:
g++ -std=c++11 -g pthread_test.cc -o pthread_test -pthread
調試過程如下:
通過以上調試我們可以發現在當前進程中的變量g_a每運行一次并不是累加1,可能會累加2,而且代碼的跳轉也能發現其實是多個線程交替執行。
基本的調試方式也就是使用我們已經說過的線程相關調試命令了。
示例2
目標:在加鎖的情況下,我們的進程全局變量的訪問變成了串行方式
測試代碼如下:
#include <iostream>
#include <thread>
#include <mutex>using namespace std;mutex g_lock;
static int g_a = 0;void pthread_func1() {for (int i = 1;i < 5000; ++i) {g_lock.lock();g_a ++;g_lock.unlock();}
}void pthread_func2() {for (int i = 5000;i < 10000; ++i) {g_lock.lock();g_a ++;g_lock.unlock();}
}int main() {thread t1(pthread_func1);thread t2(pthread_func2);t1.join();t2.join();return 0;
}
編譯調試過程如下:
此時可以看到我們加了mutex的鎖之后對于整個進程來說,執行一次變量只會加一,顯然滿足了全局變量狀態變化的邏輯
總結
源代碼以及運行過程中各個線程的子變量信息實時顯示,且通過斷點 我們清楚得看到了代碼運行過程中的跳轉邏輯,可以說解決問題的效率事半功倍了。
總結
以上是生活随笔為你收集整理的g-gdb 调试多线程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 其实直升机是不是很脆弱的?为啥电影中的直
- 下一篇: 求一个好听的吃货名字