【ARM Linux 系统稳定性分析入门及渐进 1 -- Crash 工具简介】
文章目录
- 1.1 Kexec 和 Kdump
- 1.1.1 Kexec 加载优点
- 1.1.2 kdump 功能
- 1.1.3 kdump原理
- 1.2 Crash tool
- 1.2.1 ramdump 机制
- 1.2.2 Crash 路径设置
- 1.2.3 Crash 常用命令
- 1.2.4 bt 栈查看
- 1.3 Kernel 常见宕机问题
- 1.3.1 死锁问题
- 1.3.2 OOPs
- 1.3.3 BUG_ON和WARN_ON
1.1 Kexec 和 Kdump
Kexec 是一种可以从当前运行的内核引导进入另一内核的工具。可以在不执行任何硬件初始化的情况下加快系统重引导速度。还可以准备好系统,以便在系统崩溃的情况下引导进入另一内核。
1.1.1 Kexec 加载优点
使用 Kexec 可将运行中的内核替换为另一内核,而无需硬性重引导。该工具非常有用,原因如下:
- 加快系统重引导速度;
- 如果需要频繁重引导系统,Kexec 可以节省大量时间;
- 避免不可靠的固件和硬件, 计算机硬件非常复杂,在系统启动期间可能会出现严重问题。并不总能立即更换掉不可靠的硬件。Kexec 可将内核引导到已初始化硬件的受控环境。这样,就可以最大程度地减少系统启动失败的风险;
- 保存崩溃内核的转储, Kexec 可以保留物理内存的内容。在生产内核发生故障后,捕获内核(在预留内存范围内运行的附加内核)会保存有故障内核的状态。保存的映像可帮助后续分析;
- 无需 bootlader 配置即可引导,当系统使用 Kexec 引导内核时,会跳过引导加载程序阶段。常规引导过程可能会由于引导加载程序配置中的错误而失败。使用 Kexec,就不需要考虑引导加载程序配置是否有效。
1.1.2 kdump 功能
kdump 是系统崩溃的时候,用来转储运行内存的一个工具。
系统一旦崩溃,内核就没法正常工作了,这个时候将由 kdump 提供一个用于捕获当前运行信息的内核,
该内核会将此时内存中的所有运行状态和数据信息收集到一个 dump core文件中以便之后分析崩溃原因。
一旦内存信息收集完成,可以让系统将自动重启。
1.1.3 kdump原理
kexec 是 kdump机制的关键,包含两部分:
内核空间的系统调用kexec_load。负责在生产内核启动时将捕获内核加载到指定地址。
用户空间的工具kexec-tools。将捕获内核的地址传递给生产内核,从而在系统崩溃的时候找到捕获内核的地址并运行。
kdump是一种基于kexec的内核崩溃转储机制。当系统崩溃时,kdump使用kexec启动到第二个内核。第二个内核通常
叫做捕获内核,以很小内存启动以捕获转储镜像。第一个内核保留了内存的一部分给第二个内核启动使用。
由于kdump利用kexec启动捕获内核,绕过了 bootloader,所以第一个内核的内存得以保留。这是内存崩溃转储的本质。
1.2 Crash tool
当系统崩溃时,通过 kdump 可以获得当时的内存转储文件 vmcore,但是该如何分析 vmcore 呢?
crash 是一个用于分析内核转储文件的工具,一般和 kdump 搭配使用。
使用 crash 时,要求调试内核 vmlinux
在编译时带有 -g 选项,即带有调试信息。
如果没有指定 vmcore,则默认使用实时系统的内存来分析。 值得一提的是,crash也可以用来分析实时的系统内存,是一个很强大的调试工具。
Crash 工具 是在 GDB 的基础之上进一步开发的,所以 Crash 工具的很多命令在 gdb 上应该都是可以直接使用的,本篇文档主要介绍如何使用 Crash 来分析panic/hang
类型的一些 bug,这里需要注意的是有些 bug,如 hang
,只能使用 etb 工具来查看最后各个 cpu 都在干什么。
1.2.1 ramdump 机制
在有些平台上,当 kernel 发生 panic 或者 hang 之后,会触发 SoC Watchdog Reset
。有些公司的做法是:reboot 之前会在 PMIC 里面的某个寄存器里面写个值,来表明重启的原因,当再次重启的时候,会去读该寄存器,获取重启的原因。因为有时抓 ramdump 文件,需要获取重启的原因,比如 发生 Kernel Panic
时,就需要获取 watch dog
重启的原因,如果检测到是 Kernel Panic 的话,就会去dump DDR 4G 的内容(因为 SoC reset
时 DDR 内容不会丢失) 到 PC
或者 SD
卡中。
1.2.2 Crash 路径设置
使用 Crash工具之间需要进行工具的路径设置,如下所示:
vim ~/.profile
export PATH=$PATH:..../devtools/crash_tools/:
source ~./profile
1.2.3 Crash 常用命令
bt -a
dis -lx function_name //函数反汇编
dis -lr function_addr //该地址反汇编
struct -o struct_name //查看结构体各成员地址偏移情况
struct struct_name addr -x //查看具体的值
crash> ps -C 0 -m //查看cpu0上面有哪些进程
CPU: 0
[0 00:00:00.024][IN]PID:3440 TASK:ffffffc042cf8000 CPU:0 COMMAND:"com.sina
[0 00:00:00.024][IN]PID:3771 TASK:ffffffc0b2915100 CPU:0 COMMAND:"ina.weib
crash> dfc_info //直接查看静态变量里面的值
crash> p/x 0xffffff80098dd000+3472 //地址的计算
crash> rd 0xffffffc0b2b65118
crash> vtop ffffff8009ea4000 //虚拟地址转为物理地址
crash> kmem -v
VMAP_AREA VM_STRUCT ADDRESS RANGE SIZE
ffffffc04862cd80 ffffffc03c875f00 ffffff8009e96000-ffffff8009ea0000 40960
ffffffc0b2b5a300 ffffffc0b2b5a280 ffffff8009ea4000-ffffff8009ea7000 12288
crash> vmap_area -x -p ffffffc0b2b5a300 //查看kernel虚拟地址的信息,-x:16进制
struct vmap_area {va_start = 0xffffff8009ea4000, //上面虚拟地址所在进程的虚拟起始地址va_end = 0xffffff8009ea7000, //上面虚拟地址所在进程的虚拟结束地址flags = 0x4, rb_node = {__rb_parent_color = 0xffffffc0ac64cd19, rb_right = 0xffffffc0acd7dd18, rb_left = 0xffffffc0b3517598}, list = {next = 0xffffffc0b2bb70b0, prev = 0xffffffc04862cdb0}, purge_list = {next = 0x0, prev = 0x0flags = 0x1, pages = 0x0, nr_pages = 0x0, phys_addr = 0xc0000000, caller = 0xffffff80083d3828 <devm_ioremap+88>}callback_head = {next = 0xffffff80088b811c <snd_soc_info_volsw>, func = 0xffffff80088b8bec <snd_soc_get_volsw>
}
/home/xiaoming/android9.1/kernel/linux/kernel/rcu/tree.c: 1717
0xffffff8008118f88 <rcu_advance_cbs+32>: ldr x2, [x29,#40]
0xffffff8008118f8c <rcu_advance_cbs+36>: ldr x3, [x2,#88]
0xffffff8008118f90 <rcu_advance_cbs+40>: cbz x3, 0xffffff8008118ff0\ <rcu_advance_cbs+136>
## dis -lx 0xffffff8008118ff0
crash> p sblog_str //查看静态变量(或者全局变量)的值,即地址值
sblog_str = $13 = (struct sblog_struct *) 0xffffffc0b2b16418
crash> struct sblog_struct 0xffffffc0b2b16418 //查看结构体成员的值struct sblog_struct {dev = 0xffffffc0b2b6a400, clk = 0xffffffc0b2b58c00, res = {cipc_base_address = 0xffffff8009fc0100, comm_sb_addr = 0xffffff8013000000 //kernel虚拟地址无法读/*struct: read error: kernel virtual address: ffffff8013000000 /*type: "gdb_readmem_callback" struct: read error: kernel virtual /*address: ffffff8013000000 type:"gdb_readmem_callback"/*<Address 0xffffff8013000000 out of bounds>, comm_addr_offst = 0xc88000, comm_base_addr = 0x17000000 <Address 0x17000000 out of bounds>, ripc_size = 0x88, irq = 0x1b, .....}
}
crash> vtop 0xffffff8009fc0100 //物理地址转换为虚拟地址
VIRTUAL PHYSICAL
ffffff8009fc0100 d40b0100 //所以对应的物理页帧
1.2.4 bt 栈查看
/* 1. 当前pc的值,也即函数 __stack_chk_fail 走到了这个位置 */
#1 [ffffffc0198bbb20] __stack_chk_fail at ffffff90080baf48 /* 存储的是上个函数的栈帧(FP)与返回地址(LR) */ ffffffc0198bbb20: ffffffc0198bbb40 ffffff9008b91914 ffffffc0198bbb30: 1ffffff803317774 ffffff9008b91680 /* 2. 函数i2cdev_ioctl_smbus当时走到了这里,/* 所以返回时需要走下一条指令:ffffff9008b91914#2 [ffffffc0198bbb40] i2cdev_ioctl_smbus at ffffff9008b91910
1.3 Kernel 常见宕机问题
1.3.1 死锁问题
常见的死锁有两种:
1)递归死锁:例如, 在中断等延迟操作中, 使用了锁,和外面的锁构成了递归死锁。一个锁导致的问题。
2)AB-BA死锁:多个锁因为处理不当而引发死锁,多个内合路径上的锁处理顺序不一致也会导致死锁。这里是多个锁导致的问题。
1.3.2 OOPs
当处理器在内核空间访问一个非法的指针时,因为虚拟地址到物理地址的映射关系没有建立,触发一个缺页异常,在缺页中断中因为该地址是非法的,内核无法为改地址建立映射关系,因此内核触发了一个Oops错误。
对于没有编译符号的二进制文件,可以使用 objdump 工具来 dump 出汇编代码,例如使用下面命令来 dump oops.o文件
arm-linux-gnueabi-objdump -d oops.o
内核提供了一个很好的脚本,可以用来帮忙快速定位问题,该脚本位于Linux 内核源代码目录的 scripts/decodecode
,首选将 log 保存到一个 txt 文件中:
./scripts/decodecode < oops.txt
1.3.3 BUG_ON和WARN_ON
对于 bug_on
当满足条件的时候,就会触发 BUG()
宏,它会调用 panic
函数主动让系统宕机,通常是一些 内核bug 才会触发 BUG_ON
,在实际产品中使用该宏需要小心。
WARN_ON
不会触发 panic 但会答应函数调用栈信息,用来提示作用。
推荐阅读:
https://documentation.suse.com/zh-cn/sles/15-SP2/html/SLES-all/cha-tuning-kexec.html
https://www.cnblogs.com/muahao/p/9884175.html
【ARM Linux 系统稳定性分析入门及渐进 1 -- Crash 工具简介】相关推荐
- 目录 - 《ARM嵌入式Linux系统开发从入门到精通》 - 免费试读 - book.csdn.net
第一部分 ARM Linux系统移植 第1章 嵌入式系统开发入门...... 2 1.1 嵌入式系统介绍..... 2 1.1.1 嵌入式系统概述..... 2 1.1.2 嵌入式系统组成..... ...
- Linux系统IO分析工具之iotop常用参数介绍
Linux系统IO分析工具之iotop常用参数介绍 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 在一般运维工作中经常会遇到这么一个场景,服务器的IO负载很高(iostat中的 ...
- linux下的arm仿真,使用QEMU仿真ARM Linux系统
使用QEMU仿真ARM Linux系统 使用方法,网上有很多文章可以参考: http://www.aurel32.net/info/debian_arm_qemu.php http://qemu-f ...
- 操作系统笔记——Linux系统实例分析、Windows系统实例分析
文章目录 传送门 Linux进程管理 Linux进程组成 Linux进程链表 Linux进程控制 用户进程创建与撤销 0,1,2号进程 Linux进程切换 Linux进程调度 内核同步 Linux储存 ...
- Linux系统编程 / 分析开源软件Triggerhappy
哈喽,我是老吴,继续记录我的学习心得 自制力太强导致低效专注 自制力很强的人的成功之道在于,在别人都放弃的情况下仍坚持不懈. 但是这反而会让他们难以关闭专注模式,导致无法进入解决难题所必要的发散模式. ...
- arm linux设置ip地址命令,ARM Linux系统修改动态IP为静态IP地址
# Wired or wireless interfaces auto eth0 #iface eth0 inet dhcp # pre-up /bin/grep -v -e " ...
- 状态观测器极点配置求解matlab,系统稳定性分析 、利用MATLAB 实现极点配置、设计状态观测器...
订 装 实验报告 实验名称系统稳定性分析.利用MATLAB 实现极点配置.设计状态观测器 系专业班 姓名学号授课老师 预定时间实验时间实验台号 一.目的要求 掌握系统稳定性的概念.学会使用MATLAB ...
- Linux系统脚本分析之rc.sysinit
Linux系统脚本分析之rc.sysinit #!/bin/bash # # /etc/rc.d/rc.sysinit - run once at boot time # # # Rerun our ...
- linux系统下键盘按键的重新映射——xmodmap工具和xev工具
虽然linux下小键盘还是不能用,但是找到一篇好文章 linux系统下键盘按键的重新映射--xmodmap工具和xev工具 文章目录 1. xev工具: 2. xmodmap工具 大家会不会有时候,感 ...
最新文章
- BP神经网络预测实例
- python爬虫为什么xpath路径正确却检索不到内容_中国知网爬虫
- 【转】文本格式导入物料凭证模板
- vue 中的el表达式_Vue中vue.filter()的使用方法介绍(过滤)
- builtins.ModuleNotFoundError: No module named ‘’scrapy.contrib‘’
- 线性代数导论2——矩阵消元
- 单表60亿记录等大数据场景的MySQL优化和运维之道 | 高可用架构
- Python爬虫编程实践 Task03
- Java英文单词翻译(API文档,IDE以及基本的java英文)
- 计算机毕设如何做?点进来,干货分享。
- SCI分区:JCR分区和中科院分区 的差别
- 打印机显示服务器脱机是什么原因,打印机显示“脱机”的原因和解决办法
- DOE实验设计操作手册
- 使用命令行把debian变成实时系统
- 人脸识别+表情识别系统
- FER 人脸表情识别
- 阿里云实时数仓搭建与组件选型
- meanShift算法介绍
- SAP License:利润中心
- 判定南京配眼镜哪家好的三步骤,轻松解决配镜烦恼
热门文章
- 【C++】基于固高驱动器的伺服电机项目调试
- ISL1208时钟芯片初始化
- 决策树(Decision Tree)算法 python简单实现
- 华清远见嵌入式c语言学习笔记
- 安徽师范大学计算机学院导师,安徽师范大学 数字计算机学院 耿焕同老师简介 联系方式 手机电话 邮箱...
- Tcl异常处理命令之try、throw
- 记录 uni-app 中对 data 的修改视图未更新的坑
- 哈工大形式语言与自动机2022期末试题
- ie调用java闪退_win7旗舰版系统位数不兼容导致IE浏览器频繁出现闪退怎么办
- March 4 2017 Week 10 Saturday