/**
死锁调试
1) -g参数
2) attach
3) info threads
4) thread + number切换到对应的线程或thread apply all bt全部设置断点*/#include#include#include
void *workThread( void *arg )
{
pthread_mutex_t mutex;
pthread_mutex_init(&mutex, 0);
usleep(1000*1000);
fprintf(stderr,"timeout we will start dead lock\n");
pthread_mutex_lock(&mutex);
pthread_mutex_lock(&mutex);
}void *AliveThread ( void *arg )
{while ( true)
{
usleep(1000*1000);
}
}int main(int argc, char *argv[])
{
pthread_t alivepid;
pthread_create(&alivepid,0,AliveThread,0);
pthread_t deadpid;
pthread_create(&deadpid, 0, workThread, 0);void *retval = 0;
pthread_join(deadpid,&retval);void *retval2 = 0;
pthread_join(alivepid,&retval2);return 0;
}
2.编译运行 lock.c
[root@localhost ~]# gcc -g lock.c -pthread
[root@localhost ~]# ./a.out
timeout we will start dead lock
(程序挂起)
3.查找进程id
[root@localhost ~]# ps -e | grep a.out
12826 pts/3 00:00:00 a.out //进程id为12826
gdb多线程调试命令:
(gdb)info threads
显示当前可调试的所有线程,每个线程会有一个GDB为其分配的ID,后面操作线程的时候会用到这个ID。
前面有*的是当前调试的线程。
(gdb)thread ID
切换当前调试的线程为指定ID的线程。
(gdb)thread apply ID1 ID2 command
让一个或者多个线程执行GDB命令command。
(gdb)thread apply all command
让所有被调试线程执行GDB命令command。
(gdb)set scheduler-locking off|on|step
估计是实际使用过多线程调试的人都可以发现,在使用step或者continue命令调试当前被调试线程的时候,其他线程也是同时执行的,怎么只让被调试程序执行呢?通过这个命令就可以实现这个需求。
off 不锁定任何线程,也就是所有线程都执行,这是默认值。
on 只有当前被调试程序会执行。
step 在单步的时候,除了next过一个函数的情况(熟悉情况的人可能知道,这其实是一个设置断点然后continue的行为)以外,只有当前线程会执行。
//显示线程堆栈信息
(gdb) bt
察看所有的调用栈
(gdb) f 3
调用框层次
(gdb) i locals
显示所有当前调用栈的所有变量
4.启动gdb attach 进程
[root@localhost ~]#gdb a.out 12826
GNU gdb (GDB) CentOS (7.0.1-45.el5.centos)
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i386-redhat-linux-gnu".
For bug reporting instructions, please see:
...
Reading symbols from /root/a.out...done.
Attaching to program: /root/a.out, process 12826
Reading symbols from /lib/libpthread.so.0...(no debugging symbols found)...done.
[Thread debugging using libthread_db enabled]
[New Thread 0xb7524b90 (LWP 12828)]
[New Thread 0xb7f25b90 (LWP 12827)]
Loaded symbols for /lib/libpthread.so.0
Reading symbols from /lib/libc.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib/libc.so.6
Reading symbols from /lib/ld-linux.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib/ld-linux.so.2
0x00502402 in __kernel_vsyscall ()
(gdb) info threads //显示所有线程信息
3 Thread 0xb7f25b90 (LWP 12827) 0x00502402 in __kernel_vsyscall ()
2 Thread 0xb7524b90 (LWP 12828) 0x00502402 in __kernel_vsyscall ()
* 1 Thread 0xb7f266c0 (LWP 12826) 0x00502402 in __kernel_vsyscall ()
(gdb) thread 2 //跳到第2个线程
[Switching to thread 2 (Thread 0xb7524b90 (LWP 12828))]#0 0x00502402 in __kernel_vsyscall ()
(gdb) bt //查看线程2的堆栈,可以发现该线程堵塞在lock.c第17行
#0 0x00502402 in __kernel_vsyscall ()
#1 0x0072e839 in __lll_lock_wait () from /lib/libpthread.so.0
#2 0x00729e9f in _L_lock_885 () from /lib/libpthread.so.0
#3 0x00729d66 in pthread_mutex_lock () from /lib/libpthread.so.0
#4 0x080485b4 in work_thread (arg=0x0) at lock.c:17
#5 0x00727912 in start_thread () from /lib/libpthread.so.0
#6 0x0066660e in clone () from /lib/libc.so.6
(gdb)
参考自 http://blog.csdn.net/openxmpp/article/details/8615000
另一篇: