Linux GDB调试死锁问题
1. 死锁介绍
1.1 锁的简介
由于多线程的模式下,各个线程并发运行(注意“并发和“并行”的区别),为了保证各个线程对公共资源的访问时出现数据不一致性的问题,出现了锁的机制。
Linux系统编程中最常见的锁机制是通过互斥量(mutex)来实现的。任一时刻只有一个线程可以对互斥量mutex上锁(或说成持有该互斥量),在被持有期间,其它线程就无法对它进行上锁(这也是互斥量名字中“互斥”的由来),其它尝试加锁的线程都会休眠(注意休眠和挂起的区别)释放cpu资源,并被记录到此互斥量的等待队列中。持有的线程释放互斥量后,内核会根据调度机制从等待队列中选择一个线程使其持有互斥量,队列中的其它线程将会继续等待。
1.2 死锁的常见形式
网上关于死锁的资料有很多,比如死锁形成的四要素等等。我这里只按我的理解以白话的形式进行说明。死锁的两种常见形式为 "AA" 和 "ABAB"
(1)AA:重复上锁
发生在同一个线程中,加锁后未解锁就再次加锁,最常发生错误的情况就是程序异常退出循环前没有释放锁,导致再次上锁后发生错误,伪代码模型如下:
(2)ABBA:多个线程持有彼此在等待的锁
线程线程1持有锁A,线程2持有锁B,同时线程1等待锁B,线程2等待锁A,这种情况下就会一直死等下去。
2. GDB调试死锁的实例
2.1 写一个死锁程序
mutex.c,代码如下:
#include<unistd.h>#include<pthread.h>pthread_mutex_t mutex_1 = PTHREAD_MUTEX_INITIALIZER;pthread_mutex_t mutex_2 = PTHREAD_MUTEX_INITIALIZER;void *pthread_test_1(void *arg){pthread_mutex_lock(&mutex_1);sleep(1); //休眠以保证pthread_test_2线程运行至持有mutex_2pthread_mutex_lock(&mutex_2);pthread_mutex_unlock(&mutex_1);pthread_mutex_unlock(&mutex_2);}void *pthread_test_2(void *arg){pthread_mutex_lock(&mutex_2);sleep(1); //休眠以保证pthread_test_1线程运行至持有mutex_1pthread_mutex_lock(&mutex_1);pthread_mutex_unlock(&mutex_2);pthread_mutex_unlock(&mutex_1);}int main(void){pthread_t tid1, tid2;pthread_create(&tid1, NULL, pthread_test_1, NULL);pthread_create(&tid2, NULL, pthread_test_2, NULL);pthread_join(&tid1, NULL);pthread_join(&tid2, NULL);return 0;}
2.2 GDB调试过程
gcc 编译:gcc mutex.c -o ppt,我这里给可执行程序随便起了一个名字叫“ppt”
(1)运行死锁程序
事先运行可执行程序./ppt,然后再启动GDB进行调试(因为正常情况很可能就是这样:事先已经运行了程序,发现它可能产生死锁,所以我们用GDB对它进行调试)。
(2)pidof命令获取进程号
(3)启用GDB,然后attach [PID]调试已经在运行的进程
注:启用gdb 然后attach [PID]发现Operation not permitted,提示,我们可以try as root。
(4)查看线程的堆栈信息
thread apply all bt:查看所有线程的堆栈信息
当发现有多个线程停留在 "__lll_lock_wait" 上时,很可能说明发生了死锁,或者其它问题比如持有锁的线程无法退出,导致其他线程都阻塞在了加锁上。
从上图可以看出pthread_test_2这个线程在等待给mutex_1上锁,pthread_test_1这个线程在等待给mutex_2上锁,还不能就此判断出发生了死锁。需要在进一步查看mutex_1和mutex_2的信息。
(5)查看锁的信息
1)如果知道互斥量的名字,可以直接运行 "print mutex_name"命令来查看。
2)如果不知道互斥量的名字,可以通过 "获取互斥量地址处的数据方式" 来查看
print *(pthread_mutex *)(address):就是从address所标识的地址处取出pthread_mutex类型的数据。
由上图可以看出,mutex_1被ID为9641的线程持有,而9641为pthread_test_1,mutex_2被ID为9642的线程持有,而9642为phtread_test_2。
综上:pthread_test_1持有mutex_1,等待mutex_2,pthread_test_2持有mutex_2,等待mutex_1,得出结论发生了死锁。
Linux GDB调试死锁问题相关推荐
- linux子系统gdp调试,Linux GDB调试 详述
今天来分享下gdb的简单调试,我这里写了个例子 三个.c文件 func1.c func2.c main.c 首先生成可调试的执行文件 gcc -g func1.c func2.c main.c -o ...
- Linux GDB分析死锁
目录 示例代码 分析 结论 示例代码 // DeadLock.cpp : 定义控制台应用程序的入口点. //#include <iostream> #include <stdlib. ...
- Linux gdb调试器
gdb的启动 --gdb 程序名 [corefile] --corefile是可选的,但能增强gdb的调试能力 --强调:启动gdb必须在编译命里加上"-g"参数,"-g ...
- Linux GDB调试
Linux 段错误调试 core 文件调试 编译时 加上 -g 使编译出的文件带 调试信息 gcc -g main.c -o main 使编译出的可执行文件带调试信息gdb main //对 main ...
- [Linux]gdb调试多进程多线程例程
gdb相信学linux的同学已经比较熟悉了吧,它是linux下代码调试工具.我们在写c语言,c++的代码时经常会用到,它有一些常用的调试命令: run(r):运行程序,如果有断点在下一个断点处停止 s ...
- Linux gdb调试(4):多进程与多线程调试
一,gdb的基础知识 1>介绍: gdb是Linux环境下的代码调试工具. 2>使用:需要在源代码生成的时候加上 -g 选项. 3>开始使用: gdb binFile 4>退出 ...
- Linux GDB调试完全教程
转自 http://blog.csdn.net/gatieme 本文将主要介绍linux下的强大调试工具是怎么完成这些工作的. 之所以要调试程序,是因为程序的运行结果和预期结果不一致,或者程序出现运行 ...
- linux gdb检查函数栈,Linux - gdb调试
调试 调试工具:gdb的使用 编译后版本 编译后的成果分为两个版本: debug版本:调试版本 -->程序员使用 release版本:最终发行版本 -->最终用户使用 gcc默认生成的是r ...
- Linux——gdb调试时多进程切换方法(attach/follow-fork-mode)
对于程序中创建子进程的情况,进行gdb调试时会默认选择父进程进行调试,假如需要对子进程进行调试就需要使用特殊方法. 共有两种方法可供选择: 目录 一.attach子进程PID ①.运行进程 ②获取进程 ...
最新文章
- sql中小数位四舍五入控制
- 高可用keepalived实例
- 框架:DAO,Service,Controller,View层之间的逻辑关系
- 他被女朋友拉黑后,写了个“舔狗”必备神器
- Apache Ignite的Node.js客户端使用入门
- 单片机设置12分频c语言,AT89C51单片机,如何实现延迟一秒
- 15款Cocos2d-x游戏源码
- merge卷积和bn层的原理
- Openwrt 路由器挂载摄像头教程
- 弹出层之3:JQuery.tipswindow
- cocos2dx lua代码和图片资源加密和解密
- 很值得看看的中文翻译The Django Book
- 嵌入式开发自救指南(嵌入式怎么高薪基本思路)
- C语言结构体,共用体所占字节数计算
- 学习MIT 6.824 部分笔记
- 华硕发布全球首款8G内存手机ZenFone VR
- 苹果cms(mac cms)安装和避雷
- css33d图片轮播_通过html+css3实现图片轮播切换
- HTML+CSS画圣诞树
- 1、关于百兆口、千兆口、万兆口端口和网线的小常识
热门文章
- 满是忧愁却又心满意足
- 银行数字化转型导师坚鹏:数字化时代普惠金融模式和产品创新
- Clickhouse Explain
- 小程序内使用setInterval()循环执行,退出页面时停止
- Python编程:聊天群的屏蔽脏话
- 魔兽中各族单位名称英文缩写
- c4d软件安装上打开不了_Homebrew :在 Mac 上无痛安装软件 | Linux 中国
- Jetson 系列——基于yolov5对火源或者烟雾的检测,使用tensorrt、c++和int8加速
- dataguard跨平台linux,Dataguard从库性能的监控
- 多线程并发-线程状态切换-后宫狗血剧情版,看完彻底掌握线程状态切换流程