使用gdb调试多线程死锁

本文介绍了如何使用gdb调试多线程死锁的情况。通过查看进程pid,附着到gdb并切换线程,分析堆栈信息找出涉及__lll_lock_wait ()的线程,从而定位到死锁原因:Thread 2持有mu2并请求mu1,而Thread 3持有mu1并请求mu2,形成循环等待导致死锁。

gdb,神器也,必须好好深入学习之

编写一段会造成死锁的代码,如下:

#include <unistd.h>
#include <stdio.h>
#include <boost/thread.hpp>

boost::mutex mu1;
boost::mutex mu2;

void func1() {
    mu1.lock();
    sleep(1);
    mu2.lock();
    printf("func1\n");
    mu2.unlock();
    mu1.unlock();
}

void func2() {
    mu2.lock();
    sleep(1);
    mu1.lock();
    printf("func2\n");
    mu1.unlock();
    mu2.unlock();
}

int main() {
    boost::thread t1(func1);
    boost::thread t2(func2);
    t1.join();
    t2.join();
    printf("Hello, world\n");

    return 0;
}

构建程序,生成可执行文件test

g++ -g -o test test.cpp -lboost_thread

这里,使用 -g 选项,在生成的可执行文件中加入调试信息,程序中试用了boost的线程库,所以要链接boost_thread

执行程序,./test,无任何输出,死锁了

另开一个终端,执行 ps -ef | grep test,查找进程test的pid,输出如下:

</pre><pre>

simic@ubuntu:~$ ps -ef | grep test
simic     2566  2480  0 19:59 pts/1    00:00:00 ./test
simic     2653  2326  0 20:02 pts/0    00:00:00 grep --color=auto test
simic@ubuntu:~$

可知test进程的pid为2566

打开gdb

simic@ubuntu:~$ gdb
GNU gdb (GDB) 7.6
Copyright (C) 2013 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 "i686-pc-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
(gdb)

附着到test进程上

(gdb) attach 2566
Attaching to pro
### 使用 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、付费专栏及课程。

余额充值