Linux中gdb调试线程死锁

本文介绍了一个简单的Linux多线程程序,该程序通过pthread库创建了两个线程,其中一个线程因尝试重复锁定同一个互斥锁而陷入死锁。使用GDB调试器附着到运行中的进程,通过分析线程堆栈来定位死锁发生的位置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Linux中gdb调试死锁

1、代码片段:

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
 
void *work_thread(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 *alive_thread(void *arg)
{
	while (1)
	{
		usleep(1000*1000);
	}
}
 
int main()
{
	pthread_t alive_pid;
	pthread_create(&alive_pid, 0, alive_thread, 0);
	pthread_t dead_pid;
	pthread_create(&dead_pid, 0, work_thread, 0);
	void *ret = NULL;
	pthread_join(dead_pid, &ret);
	void *ret2 = NULL;
	pthread_join(alive_pid, &ret2);
	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

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 <http://gnu.org/licenses/gpl.html>
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:
<http://www.gnu.org/software/gdb/bugs/>...
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) 
### 使用 GDB 调试 C/C++ 多线程程序中的死锁问题 #### 启动 GDB 并附加到目标进程 当遇到多线程应用程序中的死锁问题时,可以使用 `gdb` 的 `-p` 参数来连接正在运行的进程,或者通过 `attach` 命令附着到指定 PID 上。这允许实时监控和诊断潜在的问题。 ```bash gdb -p <pid> # 或者 gdb attach <pid> [^1] ``` #### 设置断点并捕获异常情况 为了更有效地定位死锁发生的具体位置,在可能引发竞争条件的地方设置断点是非常有帮助的。可以通过函数名、文件路径加行号等方式设定这些断点: ```cpp break pthread_mutex_lock continue ``` 一旦触发了上述断点,则意味着某个线程正试图获取互斥量锁定,此时应检查当前上下文环境以确认是否存在其他等待相同资源的情况。 #### 查看所有活动线程及其状态 在检测到疑似死锁现象之后,执行如下命令可查看整个进程中各个线程的状态信息: ```bash info threads ``` 该指令会列出每一个活跃线程对应的编号(ID)、调用栈轨迹以及其他有用的数据;对于分析哪个或哪些特定线程陷入了僵持局面特别重要[^2]。 #### 切换至感兴趣的线程进行深入调查 假设已经识别出了几个可疑的目标对象,那么就可以依次切换过去进一步探究其内部逻辑是否存在问题: ```bash thread <tid> bt full frame <n> print variable_name list ``` 这里展示了如何选定某一线程作为焦点,并打印完整的回溯记录以便更好地理解代码流走向;还可以借助 `frame` 和 `print` 来观察局部变量值的变化趋势,甚至读取源码片段辅助判断。 #### 应用专用库支持复杂场景下的调试工作 针对某些特殊架构平台上的应用开发而言,可能会涉及到第三方提供的线程管理接口实现细节。这时就需要加载相应的符号表才能顺利完成后续操作: ```bash set solib-search-path /path/to/libs sharedlibrary libpthread ``` 此外,如果项目依赖于非标准扩展功能的话,务必确保已安装好匹配版本的支持包,比如 Linux 下面提到过的 `libthread_db.so.1` 文件就是用来增强对 POSIX 线程 API 的解析能力[^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值