使用GDB进行多线程调试,查看互斥变量。
演示源码如下:
#include <pthread.h> #include <stdlib.h> #include <stdio.h> #include <unistd.h> static void* thread_func(void* args); pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER; int sum = 0; #define MAX_NUM 10000 int main(int argc, char** argv) { int seq = 0; pthread_t thread_handle; for ( seq = 0; seq < 5; seq++) { int* tmp_seq = (int*)malloc(sizeof(int)); *tmp_seq = seq; pthread_create(&thread_handle, NULL, thread_func, tmp_seq); } while ( 1 ) sleep(20); return 0; } static void* thread_func(void* args) { int thread_seq = *(int*)args; free(args); while ( 1 ) { sleep(thread_seq + 2); pthread_mutex_lock(&g_mutex); if ( sum < MAX_NUM ) sum++; else sum = 0; printf("in thread %d, sum is %d\n", thread_seq, sum); pthread_mutex_unlock(&g_mutex); } }
编译
gcc -o demo -g demo.c -lpthread
运行效果如下:
in thread 0, sum is 1 in thread 1, sum is 2 in thread 2, sum is 3 in thread 0, sum is 4 in thread 3, sum is 5 in thread 4, sum is 6 in thread 1, sum is 7 in thread 0, sum is 8 in thread 2, sum is 9
使用GDB进行调试
gdb ./demo
设置断点 gdb) br 32
查看运行的线程
gdb) info threads Id Target Id Frame 6 Thread 0xb5c9eb40 (LWP 914) "demo" 0xb7fdd416 in __kernel_vsyscall () 5 Thread 0xb649fb40 (LWP 913) "demo" 0xb7fdd416 in __kernel_vsyscall () 4 Thread 0xb6ca0b40 (LWP 912) "demo" 0xb7fdd416 in __kernel_vsyscall () 3 Thread 0xb74a1b40 (LWP 911) "demo" 0xb7fdd416 in __kernel_vsyscall () * 2 Thread 0xb7ca2b40 (LWP 910) "demo" thread_func (args=0x804a008) at demo.cpp:32 1 Thread 0xb7ca4700 (LWP 906) "demo" 0xb7fdd416 in __kernel_vsyscall ()
查看当前线程的函数调用堆栈
gdb) bt full
查看哪个线程拥有互斥变量,首先需要知道pthread_mutex_t的具体结构是什么。
gdb) whatis g_mutex type = pthread_mutex_t gdb) set print pretty #让GDB输出效果排版的好看一些 gdb) ptype g_mutex type = union pthread_mutex_t { pthread_mutex_t::__pthread_mutex_s __data; char __size[24]; long __align; }
打印出g_mutex的具体内容:
gdb) p g_mutex $2 = { __data = { __lock = 1, __count = 0, __owner = 910, __kind = 0, __nusers = 1, { __spins = 0, __list = { __next = 0x0 } } }, __size = "\001\000\000\000\000\000\000\000\216\003\000\000\000\000\000\000\001\000\000\000\000\000\000", __align = 1 }
各位看官,注意上述输出中,owner表示当前拥有g_mutex的线程。
那么谁是910呢,上面用”info threads"只输出了1,2,3,4,5,6无法对应,ok. 用点top小技巧,
top -H -p 906
906表示demo的进程ID,-H表示打印出所有的线程。
当前拥有g_mutex是910,那么应该是第二号线程,即thread_seq为0的线程。
如果想在程序运行的时候知道当前线程中类似于top输出的pid值,可以通过如下方法。
/*#method 1*/ pid_t gettid(void); /************************************** *#method 2 using the following system call **************************************/ #include <sys/syscall.h> pid_t tid = (pid_t) syscall (SYS_gettid);
最后需要提醒的是,当设定断点停下来的时候,其它线程其实还是可以继续运行的。如果只想让当前线程可以运行,其它的全部停下来的话。请用下列的指令。
gdb) set scheduler-locking on
关于这个内容,可以参考链接http://sourceware.org/gdb/onlinedocs/gdb/All_002dStop-Mode.html
时间: 2024-11-18 01:58:31