Linux Kdump分析宕机问题案例

2024-01-11 18:36

本文主要是介绍Linux Kdump分析宕机问题案例,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 1. 查看问题原因
  • 2. 找出哪一行代码触发的宕机
  • 3. 查看宕机函数传入参数的值
    • 方法一:使用struct查看结构体的值
    • 方法二:使用rd命令查看对应内存的值

1. 查看问题原因

GNU gdb (GDB) 7.6
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-unknown-linux-gnu"...WARNING: kernel relocated [680MB]: patching 85605 gdb minimal_symbol valuesplease wait... (patching 85605 gdb minimal_symbol values)KERNEL: /usr/lib/debug/lib/modules/3.10.0-957.el7.x86_64/vmlinuxDUMPFILE: vmcore  [PARTIAL DUMP]CPUS: 2DATE: Fri Jan  5 17:59:15 2024UPTIME: 00:03:25
LOAD AVERAGE: 0.44, 0.67, 0.31TASKS: 490NODENAME: localhost.localdomainRELEASE: 3.10.0-957.el7.x86_64VERSION: #1 SMP Thu Nov 8 23:39:32 UTC 2018MACHINE: x86_64  (3407 Mhz)MEMORY: 3 GBPANIC: "BUG: unable to handle kernel NULL pointer dereference at 0000000000000050"PID: 3943COMMAND: "insmod"TASK: ffff8ebeece52080  [THREAD_INFO: ffff8ebedfa48000]CPU: 0STATE: TASK_RUNNING (PANIC)

其中PANIC直接指出了触发宕机的原因
上述案例中发生崩溃的原因是"BUG: unable to handle kernel NULL pointer dereference at 0000000000000050",即内核发生了不能处理的空指针引用。

2. 找出哪一行代码触发的宕机

  1. 查看堆栈信息
crash> bt
PID: 3943   TASK: ffff8ebeece52080  CPU: 0   COMMAND: "insmod"#0 [ffff8ebedfa4b930] machine_kexec at ffffffffab863674#1 [ffff8ebedfa4b990] __crash_kexec at ffffffffab91ce12#2 [ffff8ebedfa4ba60] crash_kexec at ffffffffab91cf00#3 [ffff8ebedfa4ba78] oops_end at ffffffffabf6c758#4 [ffff8ebedfa4baa0] no_context at ffffffffabf5aa7e#5 [ffff8ebedfa4baf0] __bad_area_nosemaphore at ffffffffabf5ab15#6 [ffff8ebedfa4bb40] bad_area_nosemaphore at ffffffffabf5ac86#7 [ffff8ebedfa4bb50] __do_page_fault at ffffffffabf6f6b0#8 [ffff8ebedfa4bbc0] do_page_fault at ffffffffabf6f915#9 [ffff8ebedfa4bbf0] page_fault at ffffffffabf6b758[exception RIP: create_oops+25]RIP: ffffffffc0854019  RSP: ffff8ebedfa4bca0  RFLAGS: 00010286RAX: 0000000000000000  RBX: ffffffffac418020  RCX: 0000000000036cdfRDX: ffff8ebedfa4bce4  RSI: ffff8ebedfa4bce4  RDI: 0000000000000000RBP: ffff8ebedfa4bcb8   R8: 68737568736e6562   R9: 007568737568736eR10: ffff8ebefa61f120  R11: fffff9f20263a900  R12: ffff8ebee8ef7120R13: ffffffffc0859000  R14: 0000000000000000  R15: ffffffffc0856000ORIG_RAX: ffffffffffffffff  CS: 0010  SS: 0018
#10 [ffff8ebedfa4bcc0] init_module at ffffffffc085909a [oops]
#11 [ffff8ebedfa4bd38] do_one_initcall at ffffffffab80210a
#12 [ffff8ebedfa4bd68] load_module at ffffffffab918f8c
#13 [ffff8ebedfa4beb8] sys_finit_module at ffffffffab919606
#14 [ffff8ebedfa4bf50] system_call_fastpath at ffffffffabf74ddbRIP: 00007fae7c472e29  RSP: 00007fff1b996bd8  RFLAGS: 00010207RAX: 0000000000000139  RBX: 0000000002239240  RCX: 00007fae7c4e4f90RDX: 0000000000000000  RSI: 000000000041a96e  RDI: 0000000000000003RBP: 000000000041a96e   R8: 0000000000000000   R9: 00007fff1b996de8R10: 0000000000000003  R11: 0000000000000206  R12: 0000000000000000R13: 0000000002239220  R14: 0000000000000000  R15: 0000000000000000ORIG_RAX: 0000000000000139  CS: 0033  SS: 002b
  • RIP: 指向造成崩溃的指令地址
  • RDI: 存储函数第一个参数的地址
  • RSI: 存储函数第二个参数的地址
  1. 加载内核模块调试信息
crash> mod -s oops  /root/rlk_lab/oops.koMODULE       NAME                            SIZE  OBJECT FILE
ffffffffc0856000  oops                           12741  /root/rlk_lab/oops.ko
  1. 查看出现问题的代码行号

ffffffffc0854019为堆栈信息中RIP所指地址。在输出信息中我们可以看到触发宕机的代码在oops_test.c文件的第16行。

crash> sym ffffffffc0854019
ffffffffc0854019 (T) create_oops+25 [oops] /root/rlk_lab/oops_test.c: 16

3. 查看宕机函数传入参数的值

堆栈中RDI,RSI分别指向了传入的第一个,第二个参数。

方法一:使用struct查看结构体的值

  1. 使用dis -l命令找到宕机触发点的代码位置
crash> dis -l kfree+316 10
crash> dis -l ffffffffc0748019 10
/root/rlk_lab/oops_test.c: 16
0xffffffffc0748019 <create_oops+25>:    mov    0x50(%rax),%rax
0xffffffffc074801d <create_oops+29>:    mov    %rax,-0x8(%rbp)
  1. 在源码中找到对应文件,查看传入的结构体类型

结合代码我们可以看到,传入的两个参数类型分别是struct vm_area_structstruct mydev_priv

int create_oops(struct vm_area_struct *vma, struct mydev_priv *priv)
{unsigned long flags;flags = vma->vm_flags;printk("flags=0x%lx, name=%s\n", flags, priv->name);return 0;
}
  1. 使用struct命令结合结构体位置,查看传入的结构体数据
crash> struct  mydev_priv ffff95f18619bce4
struct mydev_priv {name = "benshushu\000\377\377\000\275\031\206\361\225\377\377j\342\303'\000\000\000\000\240\360\001\000\000\000\000\000\200a\350\224\361\225\377\377\000\320t\300\377\377\377\377 \200\241\263\377\377\377\377\300\036`\212",i = 10
}

参数的地址由堆栈中的RSIRDI指出。

方法二:使用rd命令查看对应内存的值

crash> rd ffff95f18619bce4
ffff95f18619bce4:  68737568736e6562                    benshush

这篇关于Linux Kdump分析宕机问题案例的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/595323

相关文章

Linux脚本(shell)的使用方式

《Linux脚本(shell)的使用方式》:本文主要介绍Linux脚本(shell)的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录概述语法详解数学运算表达式Shell变量变量分类环境变量Shell内部变量自定义变量:定义、赋值自定义变量:引用、修改、删

MyBatis Plus 中 update_time 字段自动填充失效的原因分析及解决方案(最新整理)

《MyBatisPlus中update_time字段自动填充失效的原因分析及解决方案(最新整理)》在使用MyBatisPlus时,通常我们会在数据库表中设置create_time和update... 目录前言一、问题现象二、原因分析三、总结:常见原因与解决方法对照表四、推荐写法前言在使用 MyBATis

六个案例搞懂mysql间隙锁

《六个案例搞懂mysql间隙锁》MySQL中的间隙是指索引中两个索引键之间的空间,间隙锁用于防止范围查询期间的幻读,本文主要介绍了六个案例搞懂mysql间隙锁,具有一定的参考价值,感兴趣的可以了解一下... 目录概念解释间隙锁详解间隙锁触发条件间隙锁加锁规则案例演示案例一:唯一索引等值锁定存在的数据案例二:

Python主动抛出异常的各种用法和场景分析

《Python主动抛出异常的各种用法和场景分析》在Python中,我们不仅可以捕获和处理异常,还可以主动抛出异常,也就是以类的方式自定义错误的类型和提示信息,这在编程中非常有用,下面我将详细解释主动抛... 目录一、为什么要主动抛出异常?二、基本语法:raise关键字基本示例三、raise的多种用法1. 抛

MySQL 设置AUTO_INCREMENT 无效的问题解决

《MySQL设置AUTO_INCREMENT无效的问题解决》本文主要介绍了MySQL设置AUTO_INCREMENT无效的问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参... 目录快速设置mysql的auto_increment参数一、修改 AUTO_INCREMENT 的值。

关于跨域无效的问题及解决(java后端方案)

《关于跨域无效的问题及解决(java后端方案)》:本文主要介绍关于跨域无效的问题及解决(java后端方案),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录通用后端跨域方法1、@CrossOrigin 注解2、springboot2.0 实现WebMvcConfig

Linux链表操作方式

《Linux链表操作方式》:本文主要介绍Linux链表操作方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、链表基础概念与内核链表优势二、内核链表结构与宏解析三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势六、典型应用场景七、调试技巧与

Go语言中泄漏缓冲区的问题解决

《Go语言中泄漏缓冲区的问题解决》缓冲区是一种常见的数据结构,常被用于在不同的并发单元之间传递数据,然而,若缓冲区使用不当,就可能引发泄漏缓冲区问题,本文就来介绍一下问题的解决,感兴趣的可以了解一下... 目录引言泄漏缓冲区的基本概念代码示例:泄漏缓冲区的产生项目场景:Web 服务器中的请求缓冲场景描述代码

Java死锁问题解决方案及示例详解

《Java死锁问题解决方案及示例详解》死锁是指两个或多个线程因争夺资源而相互等待,导致所有线程都无法继续执行的一种状态,本文给大家详细介绍了Java死锁问题解决方案详解及实践样例,需要的朋友可以参考下... 目录1、简述死锁的四个必要条件:2、死锁示例代码3、如何检测死锁?3.1 使用 jstack3.2

详解Linux中常见环境变量的特点与设置

《详解Linux中常见环境变量的特点与设置》环境变量是操作系统和用户设置的一些动态键值对,为运行的程序提供配置信息,理解环境变量对于系统管理、软件开发都很重要,下面小编就为大家详细介绍一下吧... 目录前言一、环境变量的概念二、常见的环境变量三、环境变量特点及其相关指令3.1 环境变量的全局性3.2、环境变