CN116841862A - 死锁检测方法 - Google Patents
死锁检测方法 Download PDFInfo
- Publication number
- CN116841862A CN116841862A CN202310425939.1A CN202310425939A CN116841862A CN 116841862 A CN116841862 A CN 116841862A CN 202310425939 A CN202310425939 A CN 202310425939A CN 116841862 A CN116841862 A CN 116841862A
- Authority
- CN
- China
- Prior art keywords
- thread
- lock
- deadlock
- address
- value
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Pending
Links
- 238000001514 detection method Methods 0.000 title claims abstract description 31
- 238000000034 method Methods 0.000 claims abstract description 26
- 101000971351 Homo sapiens KRR1 small subunit processome component homolog Proteins 0.000 claims description 3
- 102100021559 KRR1 small subunit processome component homolog Human genes 0.000 claims description 3
- 230000007717 exclusion Effects 0.000 description 7
- 230000009286 beneficial effect Effects 0.000 description 2
- 230000007547 defect Effects 0.000 description 2
- 230000004048 modification Effects 0.000 description 2
- 238000012986 modification Methods 0.000 description 2
- 238000004806 packaging method and process Methods 0.000 description 2
- 238000004590 computer program Methods 0.000 description 1
- 230000000694 effects Effects 0.000 description 1
- 238000009434 installation Methods 0.000 description 1
- 238000013507 mapping Methods 0.000 description 1
- 230000003068 static effect Effects 0.000 description 1
- 238000012360 testing method Methods 0.000 description 1
Classifications
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F11/00—Error detection; Error correction; Monitoring
- G06F11/36—Preventing errors by testing or debugging software
- G06F11/3668—Software testing
- G06F11/3672—Test management
- G06F11/3688—Test management for test execution, e.g. scheduling of test suites
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F11/00—Error detection; Error correction; Monitoring
- G06F11/36—Preventing errors by testing or debugging software
- G06F11/3668—Software testing
- G06F11/3696—Methods or tools to render software testable
Landscapes
- Engineering & Computer Science (AREA)
- Theoretical Computer Science (AREA)
- Computer Hardware Design (AREA)
- Quality & Reliability (AREA)
- Physics & Mathematics (AREA)
- General Engineering & Computer Science (AREA)
- General Physics & Mathematics (AREA)
- Debugging And Monitoring (AREA)
Abstract
本发明提供了一种死锁检测算法,包括如下步骤:获取被测进程的所有线程ID;获取每个线程里的寄存器rdi和寄存器rip;找到线程库libpthread.so的代码段地址;判断前面获取的线程的寄存器rip是否在线程库代码段地址内,如果在,则计算rip在libpthread.so的代码段里的偏移量offset1;获取拿锁等待函数的偏移量offset2和代码长度length;比较offset1‑offset2与length的大小,如果前者较小则可判定当前线程阻塞在拿锁函数上;获取锁的属主线程ID;根据所有线程ID、锁地址及锁的属主线程ID,判断被测进程是否处于死锁状态。本发明无需在用户编写的C/C++代码中插入其他代码即可快速检测出程序中是否发生了死锁,能够提高用户检测死锁程序的效率。
Description
技术领域
本发明涉及程序测试技术领域,具体涉及一种死锁检测方法。
背景技术
在Linux操作系统中使用Pthreads多线程库开发C、C++程序时,如果程序设计不当,当两个或两个以上的线程在执行过程中,因为争夺资源而造成的一种相互等待的状态,由于存在一种环路的锁依赖关系而永远地等待下去,如果没有外部干涉,这种状态将不会发生改变,此时的这个状态称之为死锁。比如线程A想获取锁mutex1,锁mutex1的属主线程(拥有锁mutex1的线程)是B,线程B想获取锁mutex2,锁mutex2的属主线程(拥有锁mutex2的线程)是C,线程C想获取锁mutex3,锁mutex3的属主线程(拥有锁mutex3的线程)是A,这样就形成了一个环路,如果三个线程都不释放自己已有的锁,结果就是谁也拿不到自己想获取的另一把锁,大家都处于等待状态,真正的业务工作无法进行。对于Linux系统上C/C++程序的死锁检测,当前已有的专利方法:
(1)一种linux用户态互斥锁死锁检测方法及系统(申请号:201610532713.1)
该方法将用户态互斥锁数据结构与lockdep数据结构进行封装;对引入内核lockdep死锁程序的用户态互斥锁接口进行封装;将封装后的用户态互斥锁接口,编译成用户态互斥锁检测动态静态链接库,生成互斥锁死锁检测库文件;根据所述互斥锁死锁检测库文件编译互斥锁死锁检测操作;执行所述互斥锁死锁检测操作,若存在死锁,则记录死锁信息。属于预先修改线程库里的锁数据结构和锁接口然后编译成新的线程库,检测时替换被检测程序调用的线程库从而记录线程、锁的等待关系,进而判断死锁的检测方法。
(2)线程死锁检测方法、装置、设备、介质和计算 机程序产品(申请号:202111280853 .1)
该方法通过获取目标线程对目标锁的操作指令(Pthread库加锁解锁函数里的的eBPF hook代码),在操作指令为申请目标锁的情况下,则调用预设的目标程序根据操作指令申请目标锁,得到用于表示是否成功申请目标锁的申请结果;调用目标程序根据申请结果确定目标线程的死锁结果。
已有的非专利方法:
使用gdb或pstack查看线程调用栈,结合线程debug库提供的线程函数的调试符号,获取线程与锁的等待关系,进而判断是否有死锁发生。
现有的检测方法主要是下面这两种情况:
(1)通过修改线程库,hook进被检测程序,统计线程与锁的使用情况,通过死锁检测算法判断程序中是否出现了死锁;
(2)使用gdb跟踪被检测程序,结合libc-dbg提供的线程符号信息,获取线程与锁资源之间的等待关系。
这两种方法在被测系统上要么需要替换Pthread线程库,要么需要安装gdb、libc-dbg软件,这样做不方便且不安全,在生产环境下如此改动系统环境,一般都是不被允许的。
发明内容
为解决已有技术存在的不足,本发明提供了一种死锁检测方法,包括如下步骤:
步骤S1:根据被测进程的进程号pid,获取该进程的所有线程ID;获取所有线程的NSpid:如果该线程运行在容器内,那么NSpid的值是两个数字,第一个数字是它在主机上的线程ID,第二个是它在容器内的线程ID; 如果线程没有运行在容器内,那么NSpid的值就是线程在主机上的ID;
步骤S2:遍历S1中获取到的线程的主机上的ID,分别获取寄存器rdi和寄存器rip的值,rdi的值保存为锁的地址,rip的值是下一步要运行的指令的地址;
步骤S3:找到线程库libpthread.so的代码段地址;
步骤S4:根据S3中获取的代码段地址,判断rip是否在libpthread.so的代码段地址内,如果不在,则直接判断当前线程不会参与死锁,结束对当前线程的操作,回到步骤S2,执行对下一个线程的判断;如果在,计算rip在libpthread.so的代码段里的偏移量offset1;
步骤S5:获取拿锁等待函数的偏移量offset2和代码长度length;
步骤S6:比较offset1-offset2与length的大小,如果前者较大,则直接判断当前线程不会参与死锁,结束对当前线程的操作,回到步骤S2,执行对下一个线程的判断;如果前者较小,则可判定当前线程阻塞在拿锁函数上,有可能会参与死锁,则继续进行步骤S7;
步骤S7:使用S2保存的锁的地址,获取从该地址偏移8字节处的值,记为该锁的属主线程ID;根据步骤S1中遍历的线程的NSpid值,确定锁的属主线程ID所对应的线程是否运行在容器内,若运行在容器内,则将锁的属主线程ID值修改为该锁的属主线程ID所对应的线程在主机上的ID;
步骤S8:使用S1中获取的线程的主机上的ID、S2中获取的锁地址、S7中获取的锁的属主线程ID,通过死锁检测算法,判断被测进程是否处于死锁状态。
其中,所述步骤S2中,遍历S1中获取到的线程ID,通过使用ptrace函数逐个跟踪,获取寄存器rdi和寄存器rip的值;
所述步骤S3中,通过读取文件/proc/${pid}/smaps,找到线程库libpthread.so的代码段地址;
所述步骤S5中,通过使用命令“objdump -tT %s | grep __lll_lock_wait”获取拿锁等待函数的偏移量offset2和代码长度length;
所述步骤S7中,使用S2保存的锁的地址,通过ptrace函数获取从该地址偏移8字节处的值,记为该锁的属主线程ID。
本发明提供的死锁检测算法,无需在用户编写的C/C++代码中插入其他代码,无需使用gdb、pstack等调试工具,无需在系统上安装调试包,即可快速检测出程序中是否发生了死锁以及各个线程拿锁、等锁的关系,能够提高用户检测死锁程序的效率。
附图说明
图1:本发明的死锁检测算法的实现流程图。
具体实施方式
为了对本发明的技术方案及有益效果有更进一步的了解,下面结合附图详细说明本发明的技术方案及其产生的有益效果。
针对现有的死锁检测方法在Linux系统上对被测系统环境影响较大,使用限制条件多,不利于生产环境下的检测,且不支持对容器服务进程的检测的缺陷,本发明提供了一种死锁检测方法,如图1所示,实现方法如下:
1、根据被测进程(指定PID的进程)的进程号pid,从/proc/${pid}/task目录下获取该进程的所有线程ID,并记录;
从/proc/${tid}/status文件获取所有线程的NSpid,如果该线程运行在容器内,那么NSpid的值是两个数字,第一个数字是它在主机上的线程ID,第二个是它在容器内的线程ID; 如果线程没有运行在容器内,那么NSpid的值就是线程在主机上的ID;
2、遍历步骤1中获取到的线程的主机上的ID,使用ptrace函数逐个跟踪,分别获取寄存器rdi和寄存器rip的值,rdi的值保存为锁的地址,rip的值是下一步要运行的指令的地址;
3、根据/proc目录下被检测线程的smaps文件里线程库libpthread.so的映射地址信息,也即,读取文件/proc/${pid}/smaps,找到线程库libpthread.so的代码段地址;
4、根据步骤3中获取的代码段地址,判断rip是否在libpthread.so的代码段内,如果不在,则当前线程不会参与死锁,退出对当前线程的判断,回到步骤S2,执行对下一个线程的判断;如果在,计算rip在libpthread.so的代码段里的偏移量offset1;
5、使用命令“objdump -tT %s | grep __lll_lock_wait”获取拿锁等待函数的偏移量offset2和代码长度length;
6、比较offset1-offset2与length的大小,如果前者较大,则当前线程不会参与死锁,退出对当前线程的判断,回到步骤S2,执行对下一个线程的判断;如果前者较小,则可判定当前线程阻塞在拿锁函数上,继续执行步骤S7;
7、在步骤6判定当前代码阻塞在拿锁函数的基础上,使用S2保存的锁的地址,也即是寄存器rdi的值,通过ptrace函数获取从该地址偏移8字节处的值,也即是该锁的属主线程ID;锁的属主线程也就是拥有该锁的线程(并不是当前判断死锁检测的线程,如当前所检测的为线程1,该线程1在步骤2保存的锁地址对应一个锁,拥有该锁的可能是线程2,此步骤的目的为找出线程2);
8、根据步骤1所遍历的所有线程的NSpid值,判断步骤7所找出的拥有当前所检测的线程对应的锁的线程是否运行在容器内,若运行在容器内,则步骤7所计算的锁的属主线程ID为该线程在容器内的ID,而非主机上的ID,此时需要将锁的属主线程ID修改为该线程在主机上的ID;
9、使用步骤1中获取的线程的主机上的ID、步骤2中获取的锁地址、步骤7或步骤8中获取的锁的属主线程ID,通过死锁检测算法,判断被测进程是否处于死锁状态。
使用本发明提出的死锁检测方法,可以达到如下效果:
(1)使用系统调用ptrace函数、Linux系统的proc文件系统、libpthread库,这些系统基础资源去判断死锁条件,不需要引入第三方软件,不改动被检测程序和系统;
(2)通过步骤8中对锁的属主线程ID进行判断,针对即使是跑在容器里面的C/C++程序也能正常检测;
(3)死锁检测工具依赖少,对系统兼容性强,使用方便,利于远程检测。
因此,使用本发明提出的死锁检测方法写成的死锁检测工具,无需在用户编写的C/C++代码中插入其他代码,无需使用gdb、pstack等调试工具,无需在系统上安装调试包,即可快速检测出程序中是否发生了死锁以及各个线程拿锁、等锁的关系,能够提高用户检测死锁程序的效率。
虽然本发明已利用上述较佳实施例进行说明,然其并非用以限定本发明的保护范围,任何本领域技术人员在不脱离本发明的精神和范围之内,相对上述实施例进行各种变动与修改仍属本发明所保护的范围,因此本发明的保护范围以权利要求书所界定的为准。
Claims (2)
1.一种死锁检测方法,其特征在于,包括如下步骤:
步骤S1:根据被测进程的进程号pid,获取该进程的所有线程ID;获取所有线程的NSpid:如果该线程运行在容器内,那么NSpid的值是两个数字,第一个数字是它在主机上的线程ID,第二个是它在容器内的线程ID; 如果线程没有运行在容器内,那么NSpid的值就是线程在主机上的ID;
步骤S2:遍历S1中获取到的线程的主机上的ID,分别获取寄存器rdi和寄存器rip的值,rdi的值保存为锁的地址,rip的值是下一步要运行的指令的地址;
步骤S3:找到线程库libpthread.so的代码段地址;
步骤S4:根据S3中获取的代码段地址,判断rip是否在libpthread.so的代码段地址内,如果不在,则直接判断当前线程不会参与死锁,结束对当前线程的操作,回到步骤S2,执行对下一个线程的判断;如果在,计算rip在libpthread.so的代码段里的偏移量offset1;
步骤S5:获取拿锁等待函数的偏移量offset2和代码长度length;
步骤S6:比较offset1-offset2与length的大小,如果前者较大,则直接判断当前线程不会参与死锁,结束对当前线程的操作,回到步骤S2,执行对下一个线程的判断;如果前者较小,则可判定当前线程阻塞在拿锁函数上,有可能会参与死锁,则继续进行步骤S7;
步骤S7:使用S2保存的锁的地址,获取从该地址偏移8字节处的值,记为该锁的属主线程ID;根据步骤S1中遍历的线程的NSpid值,确定锁的属主线程ID所对应的线程是否运行在容器内,若运行在容器内,则将锁的属主线程ID值修改为该锁的属主线程ID所对应的线程在主机上的ID;
步骤S8:使用S1中获取的线程的主机上的ID、S2中获取的锁地址、S7中获取的锁的属主线程ID,通过死锁检测算法,判断被测进程是否处于死锁状态。
2.如权利要求1所述的死锁检测方法,其特征在于,
所述步骤S2中,遍历S1中获取到的线程ID,通过使用ptrace函数逐个跟踪,获取寄存器rdi和寄存器rip的值;
所述步骤S3中,通过读取文件/proc/${pid}/smaps,找到线程库libpthread.so的代码段地址;
所述步骤S5中,通过使用命令“objdump -tT %s | grep __lll_lock_wait”获取拿锁等待函数的偏移量offset2和代码长度length;
所述步骤S7中,使用S2保存的锁的地址,通过ptrace函数获取从该地址偏移8字节处的值,记为该锁的属主线程ID。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202310425939.1A CN116841862A (zh) | 2023-04-20 | 2023-04-20 | 死锁检测方法 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202310425939.1A CN116841862A (zh) | 2023-04-20 | 2023-04-20 | 死锁检测方法 |
Publications (1)
Publication Number | Publication Date |
---|---|
CN116841862A true CN116841862A (zh) | 2023-10-03 |
Family
ID=88162351
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN202310425939.1A Pending CN116841862A (zh) | 2023-04-20 | 2023-04-20 | 死锁检测方法 |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN116841862A (zh) |
Cited By (1)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN117873740A (zh) * | 2024-03-12 | 2024-04-12 | 麒麟软件有限公司 | 基于gdb的进程死锁关系图构建方法、装置及存储介质 |
-
2023
- 2023-04-20 CN CN202310425939.1A patent/CN116841862A/zh active Pending
Cited By (2)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN117873740A (zh) * | 2024-03-12 | 2024-04-12 | 麒麟软件有限公司 | 基于gdb的进程死锁关系图构建方法、装置及存储介质 |
CN117873740B (zh) * | 2024-03-12 | 2024-06-07 | 麒麟软件有限公司 | 基于gdb的进程死锁关系图构建方法、装置及存储介质 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
KR101143214B1 (ko) | 멀티스레드된 프로그램에서의 잠재적 레이스를 검출하기위한 방법 및 시스템 | |
US5895494A (en) | Method of executing perform locked operation instructions for supporting recovery of data consistency if lost due to processor failure, and a method of recovering the data consistency after processor failure | |
US6009269A (en) | Detecting concurrency errors in multi-threaded programs | |
US7275239B2 (en) | Run-time wait tracing using byte code insertion | |
US8250543B2 (en) | Software tracing | |
US8095921B2 (en) | Identifying code that wastes time switching tasks | |
US20110258608A1 (en) | Method and apparatus to locate bottleneck of java program | |
US7698690B2 (en) | Identifying code that wastes time performing redundant computation | |
US20080052677A1 (en) | System and method for mitigating repeated crashes of an application resulting from supplemental code | |
CN107479980B (zh) | 一种检测应用中死锁的方法与设备 | |
US6978399B2 (en) | Debug thread termination control points | |
US20110154121A1 (en) | Concurrency test effictiveness via mutation testing and dynamic lock elision | |
US7765434B2 (en) | Resource efficient software tracing for problem diagnosis | |
CN116841862A (zh) | 死锁检测方法 | |
CN111027054A (zh) | 基于安卓系统判断应用程序在多开环境中运行方法、系统 | |
CA2811617C (en) | Commit sensitive tests | |
US20100174711A1 (en) | Concurrency object classification | |
Dong et al. | Concurrency-related flaky test detection in android apps | |
CN110781075A (zh) | 一种内存泄漏的检测方法、装置、系统及存储介质 | |
US7657792B2 (en) | Identifying race conditions involving asynchronous memory updates | |
JPH04229340A (ja) | 共用メモリマルチプロセッサコンピュータのデバッグシステム | |
CN115795489A (zh) | 一种基于硬件级进程跟踪的软件漏洞静态分析方法及装置 | |
CN112199642A (zh) | 一种安卓系统反调试的检测方法、移动终端及存储介质 | |
US8930420B2 (en) | Orphan object tracking for objects having acquire-release semantics | |
CN117742897B (zh) | 一种基于容器镜像漏洞自动修复的实现方法 |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
PB01 | Publication | ||
PB01 | Publication | ||
SE01 | Entry into force of request for substantive examination | ||
SE01 | Entry into force of request for substantive examination |