一次内核 crash 的排查记录

使用的发行版本是 CentOS,内核版本是 3.10.0,在正常运行的情况下内核发生了崩溃,还好有 vmcore 生成。

准备排查环境

  1. crash
  2. 内核调试信息rpm,下载的两个 rpm 版本必须和内核版本一致

排查

准备好生成的 vmcore

  1. 进入 crash
    [zzz@localhost kernel-debug]# crash ../vmcore /usr/lib/debug/lib/modules/3.10.0-327.el7.x86_64/vmlinux
  2. 可以看到直接原因是访问了空指针 (0000000000000008)
        KERNEL: /usr/lib/debug/lib/modules/3.10.0-327.el7.x86_64/vmlinux
    DUMPFILE: ../vmcore [PARTIAL DUMP]
    CPUS: 8
    DATE: Wed Apr 29 19:40:42 2020
    UPTIME: 335 days, 01:46:01
    LOAD AVERAGE: 23.98, 26.19, 15.75
    TASKS: 688
    NODENAME: localhost.localdomain
    RELEASE: 3.10.0-327.el7.x86_64
    VERSION: #1 SMP Thu Nov 19 22:10:57 UTC 2015
    MACHINE: x86_64 (3408 Mhz)
    MEMORY: 15.6 GB
    PANIC: "BUG: unable to handle kernel NULL pointer dereference at 0000000000000008"
    PID: 76
    COMMAND: "kswapd0"
    TASK: ffff88044beba280 [THREAD_INFO: ffff88044bef0000]
    CPU: 2
    STATE: TASK_RUNNING (PANIC)
  3. 观察堆栈,看代码层面大概是哪里产生的问题
    crash> bt
    PID: 76 TASK: ffff88044beba280 CPU: 2 COMMAND: "kswapd0"
    #0 [ffff88044bef3610] machine_kexec at ffffffff81051beb
    #1 [ffff88044bef3670] crash_kexec at ffffffff810f2542
    #2 [ffff88044bef3740] oops_end at ffffffff8163e1a8
    #3 [ffff88044bef3768] no_context at ffffffff8162e2b8
    #4 [ffff88044bef37b8] __bad_area_nosemaphore at ffffffff8162e34e
    #5 [ffff88044bef3800] bad_area_nosemaphore at ffffffff8162e4b8
    #6 [ffff88044bef3810] __do_page_fault at ffffffff81640fce
    #7 [ffff88044bef3868] do_page_fault at ffffffff81641113
    #8 [ffff88044bef3890] page_fault at ffffffff8163d408
    [exception RIP: down_read_trylock+9]
    RIP: ffffffff810aa989 RSP: ffff88044bef3940 RFLAGS: 00010202
    RAX: 0000000000000000 RBX: ffff8801b4f9ff80 RCX: 0000000000000000
    RDX: 0000000000000000 RSI: 0000000000000001 RDI: 0000000000000008
    RBP: ffff88044bef3940 R8: 0000000000000000 R9: 0000000000017bc0
    R10: ffff880465fd8000 R11: 0000000000000000 R12: ffff8801b4f9ff81
    R13: ffffea00047dfbc0 R14: 0000000000000008 R15: 0000000000000001
    ORIG_RAX: ffffffffffffffff CS: 0010 SS: 0018
    #9 [ffff88044bef3948] page_lock_anon_vma_read at ffffffff811a2e65
    #10 [ffff88044bef3978] page_referenced at ffffffff811a30e7
    #11 [ffff88044bef39f0] shrink_page_list at ffffffff8117d264
    #12 [ffff88044bef3b28] shrink_inactive_list at ffffffff8117df3a
    #13 [ffff88044bef3bf0] shrink_lruvec at ffffffff8117ea05
    #14 [ffff88044bef3cf0] shrink_zone at ffffffff8117ee66
    #15 [ffff88044bef3d48] balance_pgdat at ffffffff8118010c
    #16 [ffff88044bef3e20] kswapd at ffffffff811803d3
    #17 [ffff88044bef3ec8] kthread at ffffffff810a5aef
    #18 [ffff88044bef3f50] ret_from_fork at ffffffff81645858

    异常发生在 down_read_trylock 函数内,后面发生了 page fault,先反汇编看一下 RIP 内地址(ffffffff810aa989)的内容:

    crash> dis -l ffffffff810aa989
    /usr/src/debug/kernel-3.10.0-327.el7/linux-3.10.0-327.el7.x86_64/arch/x86/include/asm/rwsem.h: 83
    0xffffffff810aa989 <down_read_trylock+9>: mov (%rdi),%rax

    打开这个内核版本的 arch/x86/include/asm/rwsem.h,可以使用网址 https://elixir.bootlin.com/linux/v3.10/source/arch/x86/include/asm/rwsem.h 打开,代码如下

    /*
    * trylock for reading -- returns 1 if successful, 0 if contention
    */
    static inline int __down_read_trylock(struct rw_semaphore *sem)
    {
    long result, tmp;
    asm volatile("# beginning __down_read_trylock\n\t"
    " mov %0,%1\n\t"
    "1:\n\t"
    " mov %1,%2\n\t"
    " add %3,%2\n\t"
    " jle 2f\n\t"
    LOCK_PREFIX " cmpxchg %2,%0\n\t"
    " jnz 1b\n\t"
    "2:\n\t"
    "# ending __down_read_trylock\n\t"
    : "+m" (sem->count), "=&a" (result), "=&r" (tmp)
    : "i" (RWSEM_ACTIVE_READ_BIAS)
    : "memory", "cc");
    return result >= 0 ? 1 : 0;
    }

    指针 sem 也就是寄存器 RAX 的值为 0000000000000008,地址解引用失败,访问空指针,引发异常。观察堆栈调用情况,都是内存管理相关操作,其中还有一个 kswapd 调用,到此,推测是内存爆了导致的

  4. 查看当时内存使用情况,观察内存使用到了 98%,而交换空间也被大量使用,符合上面函数调用的推导
    crash> kmem -i
    PAGES TOTAL PERCENTAGE
    TOTAL MEM 3962164 15.1 GB ----
    FREE 46698 182.4 MB 1% of TOTAL MEM
    USED 3915466 14.9 GB 98% of TOTAL MEM
    SHARED 224712 877.8 MB 5% of TOTAL MEM
    BUFFERS 0 0 0% of TOTAL MEM
    CACHED 555017 2.1 GB 14% of TOTAL MEM
    SLAB 136079 531.6 MB 3% of TOTAL MEM TOTAL HUGE 0 0 ----
    HUGE FREE 0 0 0% of TOTAL HUGE TOTAL SWAP 4194303 16 GB ----
    SWAP USED 3042976 11.6 GB 72% of TOTAL SWAP
    SWAP FREE 1151327 4.4 GB 27% of TOTAL SWAP COMMIT LIMIT 6175385 23.6 GB ----
    COMMITTED 9409769 35.9 GB 152% of TOTAL LIMIT
  5. 查看当时进程使用情况(节选),几乎全部是页面交换进程在运行
    crash> ps
    PID PPID CPU TASK ST %MEM VSZ RSS COMM
    > 0 0 0 ffffffff81951440 RU 0.0 0 0 [swapper/0]
    > 0 0 1 ffff88044f942e00 RU 0.0 0 0 [swapper/1]
    0 0 2 ffff88044f943980 RU 0.0 0 0 [swapper/2]
    > 0 0 3 ffff88044f944500 RU 0.0 0 0 [swapper/3]
    > 0 0 4 ffff88044f945080 RU 0.0 0 0 [swapper/4]
    0 0 5 ffff88044f945c00 RU 0.0 0 0 [swapper/5]
    > 0 0 6 ffff88044f946780 RU 0.0 0 0 [swapper/6]
    > 0 0 7 ffff88044f947300 RU 0.0 0 0 [swapper/7]
    1 0 7 ffff88044f848000 IN 0.0 189172 3080 systemd
    2 0 0 ffff88044f848b80 IN 0.0 0 0 [kthreadd]
    3 2 0 ffff88044f849700 IN 0.0 0 0 [ksoftirqd/0]
    5 2 0 ffff88044f84ae00 IN 0.0 0 0 [kworker/0:0H]
    7 2 0 ffff88044f84c500 IN 0.0 0 0 [migration/0]
    8 2 7 ffff88044f84d080 IN 0.0 0 0 [rcu_bh]

到此,问题可以锁定为是在大量内存页交换导致的问题,但是具体的代码逻辑并不能确定是为何处。而当时crash的时间也是在急需内存的操作下发生了,需要避免的地方也只有关闭一些服务释放出内存,在该操作完成后再启动服务。

一次内核 crash 的排查记录的更多相关文章

  1. FastDFS----recovery状态问题排查记录

     FastDFS问题排查记录现象今天有人反馈,客户端部分图标时而不能显示问题定位用jemter将图片地址进行简单测试后,发现偶尔有404 NOT FOUND的情况在服务器上对八台nginx分别进行测试 ...

  2. Linux 遭入侵,挖矿进程被隐藏排查记录

    今天来给大家分享下这两天遇到的一个问题,服务器被挖矿了,把我的排查记录分享下,希望能帮到有需要的同学. 问题原因 多台服务器持续告警CPU过高,服务器为K8s的应用节点,正常情况下CPU使用率都挺低的 ...

  3. Linux内核Crash分析

    转载自:http://linux.cn/article-3475-1.html 在工作中经常会遇到一些内核crash的情况,本文就是根据内核出现crash后的打印信息,对其进行了分析,使用的内核版本为 ...

  4. Shiro权限管理框架(五):自定义Filter实现及其问题排查记录

    明确需求 在使用Shiro的时候,鉴权失败一般都是返回一个错误页或者登录页给前端,特别是后台系统,这种模式用的特别多.但是现在的项目越来越多的趋向于使用前后端分离的方式开发,这时候就需要响应Json数 ...

  5. linux的crash之hardlock排查记录

    3.10.0-327的内核,crash记录如下: KERNEL: vmlinux DUMPFILE: vmcore [PARTIAL DUMP] CPUS: 48 DATE: Wed Oct 18 2 ...

  6. 嵌入式开发之内核内存异常排查---关闭oom killer

    通过执行以下命令,可以在1分钟内对系统资源使用情况有个大致的了解.uptimedmesg | tailvmstat 1mpstat -P ALL 1pidstat 1iostat -xz 1free ...

  7. systemd之导致内核 crash

    本文主要讲解linux kernel panic系列其中一种情况: Attempted to kill init! exitcode=0x0000000b 背景:linux kernel 的panic ...

  8. 【原创】访问Linux进程文件表导致系统异常复位的排查记录

    前提知识: Linux内核.Linux 进程和文件数据结构.vmcore解析.汇编语言 问题背景: 这个问题出自项目的一个安全模块,主要功能是确定某进程是否有权限访问其正在访问的文件. 实现功能时,需 ...

  9. 如何更方便的查看Linux内核代码的更新记录【转】

    转自:http://blog.csdn.net/lee244868149/article/details/44302819 Linux内核的更新非常的快,如何快速的了解这些更新呢?最一般的办法就是把新 ...

随机推荐

  1. Java中常用的七个阻塞队列介绍第一篇

    Java中常用的七个阻塞队列介绍第一篇 在上一篇我们对Java中的队列分类做了简单的介绍.本文咱们主要来聊聊阻塞队列中的七个常用子类.这七个阻塞队列的学习步骤:先看源码,分析完源码之后,我们再来对每个 ...

  2. HttpWebRequest在Post的时候,遇到特殊符号+号(加号)变成空格了

    今天在调用一个外部接口的时候遇到一个问题,外部接口说要用FOMR的POST方法提交. OK,没问题,我加了个ASPX页面,里面加了个FORM表单和一些元素,提交,返回值成功.注意看下面这一句:但返回值 ...

  3. D. Feeding Chicken(构造)

    题目大意:将k个鸡放到一个n*m的矩阵中,要求每个鸡所占的rice的个数只差最小 题解:构造,设一共有cnt个rice,可以分cnt/k个,即每一只鸡要么占用cnt/k个rice,要么占cnt/k+1 ...

  4. 莫名的证书错误...ERROR ITMS-90035:"Invalid Signature.

    请删除 .DS_Store 这种类似的文件再尝试

  5. 今天我们谈一下HTML标签中的<map>标签的用法和使用场景

    首先我们看下这个标签到底是干什么的! W3C的定义: 然后兼容性: 然后与之配套使用的另一个标签: <area/>规定其区域: 我们来看看<map>标签支不支持全局属性:=== ...

  6. 1. git 本地给远程仓库创建分支 三步法

    命令如下: 1:本地创建分支dev 1 2 Peg@PEG-PC /D/home/myself/Symfony (master) $ git branch dev 2:下面是把本地分支提交到远程仓库 ...

  7. [php] 简单的实现一个错误接管类

    自己弄的一个错误接管类: <?php //---------------------------------- // Leephp 错误接管类 // 2017-07-06 // Pengchon ...

  8. Java类的使用

    在一个Java文件中写两个类:一个基本的类,一个测试类.注意:文件名称和测试类名称一致. 如何使用呢?创建对象使用.如何创建对象呢?格式:类名 对象名 = new 类名(); Student s = ...

  9. Python之学会测试,让开发更加高效(一)

      前几天,听了公司某位大佬关于编程心得的体会,其中讲到了"测试驱动开发",感觉自己的测试技能薄弱,因此,写下这篇文章,希望对测试能有个入门.这段时间,笔者也体会到了测试的价值,一 ...

  10. [Qt] QlineEdit 限制输入,例如只能输入整数

    要注意validor的作用域,如果超出作用域,则会无效.例如下面的代码,在UI的类的构造函数里.所以要new一个validtor. QIntValidator *intValidator = new ...