AIOT人人都是极客

文章数:843 被阅读:785035

账号入驻

用crash分析内核死锁的一次实践

最新更新时间:2021-09-04 00:19
    阅读数:

【推荐阅读】

什么是死锁?

内核死锁的debug方法

上文讲了通过lockdep的方式可以debug出死锁的信息,但是如果出问题的系统没有lockdep的配置,或者没有相关的日志该怎么办?这里分享通过crash工具来动态检测死锁时的问题(除了crash工具外用trace32更方便,可参考https://blog.csdn.net/forever_2015/article/details/77434580)。

用crash初步分析

一般卡死时可能是因为核心线程处在UNINTERRUPTIBLE状态,所以先在crash环境下用ps命令查看系统中UNINTERRUPTIBLE状态的线程,参数-u可过滤掉内核线程:

bt命令可查看某个线程的调用栈,我们看一下上面UN状态的最关键的watchdog线程:

从调用栈中可以看到proc_pid_cmdline_read()函数中被阻塞的,对应的代码为:

static ssize_t proc_pid_cmdline_read(struct file *file, char __user *buf,
         size_t _count, loff_t *pos)
{
  ......
 tsk = get_proc_task(file_inode(file));
 if (!tsk)
  return -ESRCH;
 mm = get_task_mm(tsk);
 put_task_struct(tsk);
  ......
 down_read(&mm->mmap_sem);
  ......
}

这里是要获取被某个线程mm的mmap_sem锁,而这个锁又被另外一个线程持有。

推导读写锁

要想知道哪个线程持有了这把锁,我们得先用汇编推导出这个锁的具体值。可用dis命令看一下proc_pid_cmdline_read()的汇编代码:

0xffffff99a680aaa0处就是调用down_read()的地方,它的第一个参数x0就是sem锁,如:

void __sched down_read(struct rw_semaphore *sem)

x0和x28寄存器存放的就是sem的值,那x21自然就是mm_struct的地址了,因为mm_struct的mmap_sem成员的offset就是104(0x68),用whatis命令可以查看结构体的声明,如:

因此我们只需要知道x21或者x28就知道mm和mmap_sem锁的值。

函数调用时被调用函数会在自己的栈帧中保存即将被修改到的寄存器,所以我们可以在down_read()及它之后的函数调用中找到这两个寄存器:

也就是说下面几个函数中,只要找到用到x21或x28,必然会在它的栈帧中保存这些寄存器。

先从最底部的down_read()开始找:

显然它没有用到x21或x28,继续看rwsem_down_read_failed()的汇编代码:

在这个函数中找到x21,它保存在rwsem_down_read_failed栈帧的偏移32字节的位置。rwsem_down_read_failed()的sp是0xffffffd6d9e4bcb0

sp + 32 =0xffffffd6d9e4bcd0,用rd命令查看地址0xffffffd6d9e4bcd0中存放的x21的值为:

用struct命令查看这个mm_struct:

这里的owner是mm_struct所属线程的task_struct:

sem锁的地址为0xffffffd76e349a00+0x68 = 0xffffffd76e349a68,所以:

分析到这里我们知道watchdog线程是在读取1651线程的proc节点时被阻塞了,原因是这个进程的mm,它的mmap_sem锁被其他线程给拿住了,那到底是谁持了这把锁呢?

持读写锁的线程

带着问题我们继续分析,通过search命令加-t参数从系统中所有的线程的栈空间里查找当前锁:

一般锁的值都会保存在寄存器中,而寄存器又会在子函数调用过程中保存在栈中。所以只要在栈空间中找到当前锁的值(0xffffffd76e349a68),那这个线程很可能就是持锁或者等锁线程

这里搜出的20个线程中19个就是前面提到的等锁线程,剩下的1个很可能就是持锁线程了:

查看这个线程的调用栈:

由于2124线程中存放锁的地址是0xffffffd6d396b8b0,这个是在handle_mm_fault()的栈帧范围内,因此可以推断持锁的函数应该是在handle_mm_fault()之前。

我们先看一下do_page_fault函数:

代码中确实是存在持mmap_sem的地方,并且是读者,因此可以确定是2124持有的读写锁阻塞了watchdog在内的19个线程。

接下来我们需要看一下2124线程为什么会持锁后迟迟不释放就可以了。

死锁

可以看出2124线程是等待fuse的处理结果,而我们知道fuse的请求是sdcard来处理的。

在log中我们看到的确有sdcard相关的UNINTERRUPTIBLE状态的线程2767

得2767线程等待的mutex锁是0xffffffd6948f4090,

它的owner的task和pid为:

先通过bt命令查找2124的栈范围为0xffffffd6d396b4b0~0xffffffd6d396be70:

从栈里面可以找到mutex:

mutex值在ffffffd6d396bc40这个地址上找到了,它是在__generic_file_write_iter的栈帧里。

那可以肯定是在__generic_file_write_iter之前就持锁了,并且很可能是ext4_file_write_iter中,查看其源码:

这下清楚了,原来2124在等待2767处理fuse请求,而2767又被2124线程持有的mutex锁给锁住了,也就是说两个线程互锁了。

本文只限于介绍如何定位死锁问题,至于如何解决涉及到模块的具体实现,由于篇幅的关系这里就不再赘述了。


5T技术资源大放送!包括但不限于:C/C++,Arm, Linux,Android,人工智能,单片机,树莓派,等等。在公众号内回复「peter」,即可免费获取!!


 记得点击分享在看,给我充点儿电吧

推荐帖子

EEWorld加磅双重礼 ELEXCON深圳国际电子展诚邀您参加
2021年9月27-29日,由博闻创意主办的ELEXCON深圳国际电子展暨嵌入式系统展将以“智能世界从这里起步!迈向智能设计-先进封测-供应链升级-生态圈”为展示主题在深圳国际会展中心(宝安新馆)举行。 在今年展会现场,ELEXCON将推出系列亮点展区: -RISC-V专区 -5G技术与车联网专区 -第三代半导体/电源专区 -SiP系统级封装与先进封测专区 -TWS&可穿戴技术专区 -AI芯片与FPGA专区 -AIoT技术与解决方案专
EEWORLD社区 综合技术交流
二手的合众达的seed-dec6416开发板,怎么验证真伪?
对方没有合众达的发票了,出价2500。外形跟合众达卖的6416开发板一样,如果用合众达给的例子程序,包括flash测试程序,SDRAM测试程序,USB测试程序,UART测试程序,BOOT测试程序等测试,如果这些测试程序输出结果都跟合众达网上的说明书一样,能否说明就是合众达的板子。没办法,没钱,只想先买个二手的学习。二手的合众达的seed-dec6416开发板,怎么验证真伪?
dsp_comm DSP 与 ARM 处理器
求书!!!!!!!!!!!
那位大侠有这两本书,现在需要,谢谢!《基于quartusII的fpga/cpld设计与实践》,陈忠平;《基于quartusII的fpga/cpld设计与应用》,赵艳华,wangjiangqiang333@163.com不胜感激!!谢谢:\'(求书!!!!!!!!!!!
wanghai333 FPGA/CPLD
有人用过的加法器和FIFO实现累加器么?
用浮点数的加法器IP核和FIFO实现累加器的运算,因为加法器有延时,导致从fifo中读取的值和输入的值不同时到达加法器的两端,而且控制fifo的读写也有问题,有哪个大神知道应该怎么做么? 有人用过的加法器和FIFO实现累加器么?
huangfujing Altera SoC
【平头哥RVB2601创意应用开发】自己动手解决NTP,显示电子时钟。
【前言】RVB2601在与自己的服务器建立连接上,同步服务器时间,初始化RTC时间。由于现有的NTP组件存在问题,几经周折后还没有弄好,只好与自己的服务同步时间。 【步骤】 1、在原来建立TCP连接的基础上,方法见:【平头哥RVB2601创意应用开发】u8g2+IP-平头哥RISC-VRVB2601活动专区-电子工程世界-论坛(eeworld.com.cn)。 2、服务器在第一次连接时返回时间: defsend_message(self,d
lugl4313820 平头哥RISC-V RVB2601活动专区
看视频赢京东卡|泰克示波器视频学习中心重磅上线!
泰克示波器视频学习中心正式上线!本期活动精挑细选出以下5大视频内容。 点击页面任意一个视频或“免费观看”按钮,填写表单,即可免费观看活动页内所有视频。 活动日期:即日起——7月23日 活动步骤: 1、点击任意一个视频或“免费观看”按钮,填写表单,即可免费观看本活动页内所有视频; 2、活动结束后,将从所有参与活动的网友中,抽取40名幸运者颁发奖品。 前往参加>>>
EEWORLD社区 综合技术交流

最新有关AIOT人人都是极客的文章

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: TI培训

北京市海淀区知春路23号集成电路设计园量子银座1305 电话:(010)82350740 邮编:100191

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2021 EEWORLD.com.cn, Inc. All rights reserved