前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如何通过堆栈分析内核Bug

如何通过堆栈分析内核Bug

原创
作者头像
Doinruehui
修改2019-02-28 15:46:58
1.9K0
修改2019-02-28 15:46:58
举报
文章被收录于专栏:Linux kernel & K8S

最近客户的centos频繁重启,但是由于没有vmcore文件产生,但客户急于解决,无法等待vmcore,所以只能尝试从堆栈角度分析内核,找出问题的根由。

问题:

问题发生在k8s的环境,由于没有开启锁触发kdump功能,所以内核不断报NMI锁住。

分析过程:

由于没有vmcore文件,只能抱着死马当活马医的心态,根据Call Trace流量代码,看是否有发现。从堆栈可以知道,CPU一直在尝试获取一个_raw_write_lock_bh.

_raw_write_lock_bh这是一个写者获取读写锁,并禁止本地软中断。那么说明其他地方已经获取了这个锁,但是一直没释放。从堆栈上的xfrm_policy_flush+0x3a,我们反汇编一下xfrm_policy_flush函数.

由于我们没有vmcore。我们无法获取为何锁.xfrm_policy_lock.无法获取。从代码来分析一下获取锁的条件。

可以得到,如果所的lock->write的值为WRITE_LOCKER_CMP,那么这个时候锁是空闲的,可以获取。

由于缺乏vmcore,我们这个时候无法获取当前lock的信息。我们再往堆栈的前一个函数继续分析。反汇编xfrm_net_init

从内核代码可以知道,发生问题的时候,由于xfrm函数初始化失败,造成了调用xfrm_policy_fini去尝试获取锁。

我们查看整个函数的逻辑发现,锁的初始化竟然在获取锁后面,如果锁没初始化,默认net最大可能就是被初始化为0,那么lock->write的值就不可能为WRITE_LOCKER_CMP,那么这个时候xfrm_finish_ini是比如无法获取到锁,会一直自旋住,直到触发了NMI。

解决方法:

从以上的分析,锁的初始化,使用比如存在问题,应该是先初始化再使用。查看当前centos最新版本,发现该函数的没做任何修改,查看上游社区发现

这个跟我们以前的分析刚好匹配,查看这个修复的对应的patch。https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=c282222a45cb9503cbfbebfdb60491f06ae84b49

从patch的的描述信息,也符合我们的分析过程。到此我们基本能判断了这个问题的根因。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 问题:
  • 分析过程:
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档