GDB多執行緒多程序除錯
gdb多執行緒除錯
gdb提供的多執行緒除錯工具
新執行緒建立自動提醒
thread thread-id實現不同執行緒之間的切換
info threads查詢存在的執行緒
thread apply [thread-id-list] [all] args在一系列執行緒上執行命令
執行緒中設定指定的斷點
set print thread-events控制列印執行緒啟動或結束是的資訊
set scheduler-locking off|on|step在使用step或是continue進行除錯的時候,其他可能也會並行的執行,如何才能夠只讓被除錯的執行緒執行呢?該命令工具可以達到這個效果。
off:不鎖定任何執行緒,也就是所有的執行緒都執行,這是預設值。
on:只有當前被除錯的執行緒能夠執行。
step:阻止其他執行緒在當前執行緒單步除錯時,搶佔當前執行緒。只有當next、continue、util以及finish的時候,其他執行緒才會獲得重新執行的機會。
示例程式碼
include
include <pthread.h>
include
void* threadPrintHello(void* arg)
{
while(1)
{
sleep(5);
std::cout << "hello" << std::endl;
}
}
void* threadPrintWorld(void* arg)
{
while(1)
{
sleep(5);
std::cout << "world" << std::endl;
}
}
int main( int argc , char* argv[])
{
pthread_t pid_hello , pid_world;
int ret = 0; ret = pthread_create(&pid_hello , NULL , threadPrintHello , NULL); if( ret != 0 ) { std::cout << "Create threadHello error" << std::endl; return -1; } ret = pthread_create(&pid_world , NULL , threadPrintWorld , NULL); if( ret != 0 ) { std::cout << "Create threadWorld error" << std::endl; return -1; } while(1) { sleep(10); std::cout << "In main thread" << std::endl; } pthread_join(pid_hello , NULL); pthread_join(pid_world , NULL); return 0;
}
執行緒建立提醒
在GNU/Linux上,如果gdb檢測一個新的執行緒,會給出如下通知
[New Thread 0x7ffff708b700 (LWP 20567)]
[New Thread 0x7ffff688a700 (LWP 20568)]
查詢已經存在的執行緒
使用info threads可以看到程式中所有執行緒的資訊
(gdb) info threads
3 Thread 0x7ffff688a700 (LWP 20568) 0x00007ffff70be8e0 in sigprocmask () from /lib64/libc.so.6
2 Thread 0x7ffff708b700 (LWP 20567) 0x00007ffff7138a3d in nanosleep () from /lib64/libc.so.6
- 1 Thread 0x7ffff7fe5720 (LWP 20564) main (argc=1, argv=0x7fffffffe628) at multithreads.cpp:39
主要包括gdb分配的執行緒id號(例如1,2,3),作業系統分配的執行緒id(例如20568),執行緒的名字以及執行緒相關的呼叫棧資訊。
切換執行緒
thread threadno可以切換到指定的執行緒,threadno就是上面gdb分配的執行緒id號。
(gdb) thread 2
[Switching to thread 2 (Thread 0x7ffff708b700 (LWP 20567))]#0 0x00007ffff7138a3d in nanosleep () from /lib64/libc.so.6
鎖定一個執行緒
預設情況下gdb不鎖定任何執行緒
(gdb) thread 2
[Switching to thread 2 (Thread 0x7ffff708b700 (LWP 20567))]#0 threadPrintHello (arg=0x0) at multithreads.cpp:10
10 std::cout << "hello" << std::endl;
(gdb) n
helloworld
In main thread
7 while(1)
(gdb) n
9 sleep(5);
(gdb) n
world
In main thread
10 std::cout << "hello" << std::endl;
當我們切換到執行緒2的時候,使用next執行的時候,發現列印的結果中包含有其他執行緒的列印資訊。
可以使用set scheduler-locking on來鎖定只有當前的執行緒能夠執行。
(gdb) thread 2
[Switching to thread 2 (Thread 0x7ffff708b700 (LWP 20567))]#0 threadPrintHello (arg=0x0) at multithreads.cpp:10
10 std::cout << "hello" << std::endl;
(gdb) set scheduler-locking on
(gdb) n
hello
7 while(1)
(gdb) n
9 sleep(5);
(gdb) n
10 std::cout << "hello" << std::endl;
(gdb) n
hello
7 while(1)
(gdb) n
9 sleep(5);
(gdb) n
10 std::cout << "hello" << std::endl;
可以發現鎖定執行緒之後,使用next執行變不會有其它執行緒的列印結果。
執行命令
使用thread apply來讓一個或是多個執行緒執行指定的命令。例如讓所有的執行緒列印呼叫棧資訊。