故障分析
记录故障分析实例
程序猿Ricky的日常干货
擅长扫地、打杂、开车。。
展开
-
centos中vmcore的生成过程窥探以及优化
vmcore生成的机制对于centos系统,如果要配置机器宕机后自动生成vmcore,应该很多人知道,需要借助于kdump服务。因此想要了解系统如何生成vmcore的,就需要从这个服务开始,首先直接查看一下该服务的运行状态:systemctl status kdump● kdump.service - Crash recovery kernel arming Loaded: loaded (/usr/lib/systemd/system/kdump.service; enabled; vendo原创 2022-03-24 12:13:30 · 3163 阅读 · 0 评论 -
使用atop和perf分析抖动问题的方法
抖动问题一般都是发生在一瞬间,可能下一秒就已经不存在了。那么对于这类问题要如何定位呢?首先还是要能收集到发生问题的瞬间,相关的系统信息。atop对于一个问题, 先从宏观的角度来寻找问题的方向,我们可以通过安装一个atop,配置为1s粒度记录系统信息,这样当抖动发生时,可以回溯系统监控信息,从宏观角度看一下可能存在问题的是哪一个模块,比如可能是io,mem还是network等等。yum -y install atop安装完成后,配置采样频率为1秒:cat /etc/sysconfig/atop原创 2021-07-15 12:11:20 · 1585 阅读 · 1 评论 -
crash中使用list遍历结构体
list [[-o] offset][-e end][-[s|S] struct[.member[,member] [-l offset]] -[x|d]] [-r|-h|-H] start如下介绍只列举常用的和容易混淆的参数:[-o] offset:用于指定next地址指针,可以不用加-o,它支持两种offset格式,一种为structure.member,另一种为一个数字当使用这个offset参数后,最后跟的start地址应该是这个结构体地址,而不是list_head地址。-s struct:原创 2021-05-17 21:38:59 · 1980 阅读 · 0 评论 -
Linux跟踪系统调用耗时的方法(高级篇)
可以使用很多种办法来trace内核系统调用耗时,比如:使用perf probe功能使用ftrace功能使用bpftrace使用bcc使用systemtapbpftrace使用bpftrace可以比较简单的实现该功能,直接使用单行命令即可:bpftrace -e 'tracepoint:syscalls:sys_enter_write { @entry[tid]= nsecs;} tracepoint:syscalls:sys_exit_write /@entry[tid]/ {$inte原创 2021-03-17 17:01:22 · 2018 阅读 · 3 评论 -
Linux跟踪系统调用耗时的方法(初级篇)
stracestrace -cp 1命令输出:strace: Process 1 attachedstrace: Process 1 detached% time seconds usecs/call calls errors syscall------ ----------- ----------- --------- --------- ---------------- 28.09 0.000084 16 5原创 2021-01-05 11:31:17 · 1051 阅读 · 0 评论 -
Linux系统平均负载是如何计算的?
关于负载的计算,它的结果是包含有小数的一个浮点数,内核中是不能使用float变量的,那么这里就采用了一个整型变量的低11位来表示小数部分。那么对于数值1来说,它就是FIXED_1,也就是需要对1进行左移11bit。实际上此时这个整型变量保存的值是1024。cat /proc/loadavg0.43 0.58 0.65 5/7010 45102那么我们通过cat命令查看负载值如上说是,它显示的是带有两个小数表示的一个浮点数,所以最后在输出这个数值时还需要做一个转换,如果从1024个值中得出这100小数原创 2020-09-03 17:58:27 · 3753 阅读 · 1 评论 -
如何检测内核模块的内存泄露
本文简单介绍两种调试内核ko时检测内存泄露的方法。slub debug需要依赖如下内核配置:CONFIG_SLUB=yCONFIG_SLUB_DEBUG=yCONFIG_SLUB_DEBUG_ON=yCONFIG_SLUB_STATS=y编译一下应用层的工具用于查看slab信息,工具代码在tools/vm目录中make slabinfo CFLAGS=-static完成之后,就可以加载自己开发的module了,场景测试后执行slabinfo查看是否存在内存泄露行为:查看slab信息:原创 2020-08-21 12:28:40 · 1336 阅读 · 0 评论 -
内核中堆栈溢出检测之VMAP_STACK特性
在Linux-4.14之前,Linux内核栈都是位于线性映射区,该区域对应的虚拟地址和物理地址具有一个固定的偏移,并且是在系统刚启动是进行过pre-mapped,因此内核在使用时不需要另外做页表映射。在2016年的时候内核引入了vmap_stack机制,它是采用vmalloc申请的内存作为内核栈的一种机制。只需要使能 CONFIG_VMAP_STACK 配置选项即可打开该功能。这个功能带来了如下...原创 2020-05-07 14:15:55 · 2510 阅读 · 0 评论 -
内存越界问题如何调试
内核里面内存越界问题是一类很常见的错误类型,当然有些也属于异常难调试的问题,这种错误行为会触发内核运行异常,假如越界访问修改了错误的数据区,情况较轻的可能导致应用获取的数据不对;情况严重的,比如修改了一个错误的地址,那么内核访问该地址时就会触发oops和panic。下面来聊聊内存越界的类型,内存越界发生在哪些情况下呢?内存问题分类内存访问异常可以分为如下几种类型:数组越界数组的长度是预先...原创 2020-04-28 20:24:17 · 3097 阅读 · 0 评论 -
内核如何检测Hung故障
系统hung故障一般认为是系统出现了异常,但是内核并没有死掉,出现这种情况,一般都是系统中的关键进程处于D状态,也就是不可中断的睡眠状态(也叫Disk Sleep)。那么什么情况下系统会处于D状态?我觉得可以分为两种情况:1.第一种为可恢复的D状态,表现为系统的卡顿,一般进程的D状态都是在获取系统资源时避免被外界异步信号打断而进入的,并且该状态正常情况下是维持时间很短的,如果是进入了D状态维...原创 2020-04-28 09:29:33 · 1935 阅读 · 0 评论 -
内核检测soft lockup事件特性
前面我已经介绍过 Linux内核故障分类和排查 这篇文章。通过前文,可以知道内核故障中有一类,叫做lockup,实际上就是死锁,分为soft lockup和hard lockup,对于hard lockup可能还需要平台的支持,那么本文就来模拟触发一下lockup的场景。在开始之前,需要做一下准备工作,编译内核,一定要打开如下的选项:CONFIG_LOCKUP_DETECTOR=yCONFI...原创 2020-04-27 20:07:38 · 2374 阅读 · 0 评论 -
Linux内核故障分类和排查
设备故障分为多种表现形式,可以把它分为3类:1.系统崩溃重启(panic)2.系统出现长时间无响应异常(hung)3.系统出现短暂卡顿(性能问题)针对第1类,一般引起的原因包括:软件bug、死锁(soft lockup、hard lockup)、指令异常abort、system error(SError)。(1)软件bug:指的时在代码上检测到运行到异常逻辑后调用BUG宏,从而产生oop...原创 2020-04-22 20:28:13 · 3517 阅读 · 0 评论 -
Linux kernel oops
本文以ARM64为例,介绍内核的Oops机制,我们使用grep搜索一下内核中可能会报Oops的地方:./arch/arm64/kernel/sys_compat.c:142: arm64_notify_die("Oops - bad compat syscall(2)", regs, &info, scno);./arch/arm64/kernel/traps.c:771: die("...原创 2019-12-09 20:24:13 · 3086 阅读 · 0 评论 -
Linux kernel panic代码解释
当Linux内核发生严重错误的时候,系统无法继续运行下去,此时内核会主动触发一个panic操作,它的执行流程分析过程如下所示:kernel/panic.c:void panic(const char *fmt, ...){ pr_emerg("Kernel panic - not syncing: %s\n", buf); ... if (panic_tim...原创 2019-12-04 14:54:09 · 4683 阅读 · 0 评论 -
initcall_debug来查看开机慢问题
1.cmdline中传入initcall_debug对于android开发环境来说,可以在device中的BoardConfig.mk中添加如下:BOARD_KERNEL_CMDLINE += initcal_debug对于linux系统,可以在defconfig中添加:CONFIG_CMDLINE="initcall_debug"当然这种方式同样适用于android设备。...原创 2018-11-19 19:12:54 · 5091 阅读 · 0 评论 -
内核中访问空指针(基于kernel-4.9)
在C语言中,我们定义了NULL来表示空指针,空指针是一个特殊的指针,它其实就是0指针,*p = NULL和*p=0是等价的写法。空指针是一个未赋值的指针,毫无意义的指针,如果访问到该地址,那么程序会出错。如果在Linux应用程序中访问NULL指针:会收到Segmentation Fault信号,一般行为是该用户进程会杀死自己,程序当然也可以捕获对应的信号自行处理,这种用户态的错误是不会导致...原创 2018-04-20 17:23:51 · 5279 阅读 · 3 评论 -
soft lockup问题的定位方法
我之前已经写了lockup问题的检测原理,https://blog.csdn.net/rikeyone/article/details/112004920,本来就来尝试梳理一下soft lockup问题触发场景和解决方法。首先需要明确一点soft lockup是一类问题,引起它的原因也是各有不同,本文只是尝试做一些梳理,把一些具有共通性的特点的问题做一些总结,可能存在有不全面的地方。第一种场景:spinlock死锁场景对于这种场景,其实很好理解,当A-B/B-A死锁发生的时候,两个进程分别去获取对方持原创 2020-12-31 18:41:38 · 1890 阅读 · 0 评论 -
x86-64平台栈帧结构与ARM64栈帧结构对比
x86-64ARM64差异点ARM64平台上的栈帧寄存器是FP,它记录的是一个函数执行过程中的栈顶(FP=SP),并且把父函数的FP保存在堆栈的栈顶,以便于回溯X86-64平台上的栈帧寄存器是RBP,它记录的是一个函数执行过程中的栈底,并且把父函数的RBP位置保存到本函数的栈底,以便于回溯...原创 2020-08-24 11:49:53 · 2172 阅读 · 3 评论 -
crash常用的调试命令
我的crash常用命令如下所示:log/dmesg: 打印出故障现场的kmsg缓冲区log_buf中的内容。struct:展示结构体的定义,或者从指定的地址开始解析一个结构体。union:与struct类似,但是用于union的展示p:print查看某个变量的值,实际上是调用gdb的p命令whatis:展示结构体、联合体等定义bt <pid>:展示调用堆栈信息,如果不加参数...原创 2020-05-08 11:07:25 · 9502 阅读 · 0 评论 -
oops堆栈分析实例
本文基于Linux-4.0,根据一个crash现场的实例,根据堆栈中的数据,反推整个函数调用流程,由于本例子存在oops,也会直接打印出backtrace,最终可以与我们的分析结果做一下比较,看看分析是否正确。/ # echo c > /proc/sysrq-triggersysrq: SysRq : Trigger a crashUnable to handle kernel NUL...原创 2020-04-24 15:06:43 · 1111 阅读 · 0 评论 -
内核打开kaslr后的调试方法
本文基于ARM64平台代码分析,ARM64平台的内核,在编译链接时,kernel代码段被链接的位置是:KIMAGE_VADDR + TEXT_OFFSET。我们可以通过查看vmlinux.lds.S链接文件查看具体内容:. = KIMAGE_VADDR + TEXT_OFFSET;.head.text : { _text = .; HEAD_TEXT}下面依次介绍各个变...原创 2020-04-23 17:51:21 · 2168 阅读 · 0 评论 -
使用crash工具分析高通ramdump
工具准备1.下载并编译arm64平台上的crash工具从github上下载crash工具源代码:git clone https://github.com/crash-utility/crash.git编译针对arm64平台的crash工具:make target=ARM64sudo make install2.解析高通的ramdump数据使用crash加载ramdump数据,...原创 2020-04-21 20:43:49 · 7335 阅读 · 1 评论 -
ARM64堆栈回溯
基于AAPCS64栈帧的组织方式先看一个实例代码程序:#include <stdio.h>int callee_func2(int a){ int b = 2; return a + b;}int callee_func1(int a){ int b = 1, c; c = callee_func2(a); return b ...原创 2020-04-20 15:47:58 · 3769 阅读 · 0 评论 -
案例分析 - OOM的内存分析
当Linux系统由于内存不足而触发了oom killer时,会在内核log中输出相关的内存信息,按照信息类型分为这几部分来介绍。第1部分首先输出的是整机的内存信息,按照指标分行整理后显示如下:Mem-Info:active_anon:81208569inactive_anon:209684 isolated_anon:0#012 active_file:72830 inactive_file:121873 isolated_file:0#012 unevictable:15512原创 2021-05-07 12:22:27 · 1870 阅读 · 0 评论 -
案例分析 - 内存泄露的排查方法
查看系统meminfo查看系统内存情况:free -h查看meminfo,:/proc/meminfo :对于内存泄露的问题,需要关注的主要有:MemTotal: 32571632 kBMemFree: 3910664 kBMemAvailable: 7495000 kBBuffers: 124784 kBCached: 6162332 kBSwapCached: 0 kB...Sla原创 2021-04-29 16:05:29 · 3239 阅读 · 0 评论 -
如何区分tty和tty0和console设备
/dev/tty设备这个设备表示的是控制终端,如果当前的shell登录环境有关联控制终端,那么执行它就可以看到回显。echo test > /dev/tty它其实是一个当前控制终端的一个别名,实际控制终端可以是伪终端(/dev/pts/x),也可以是虚拟控制台(/dev/ttyx)。/dev/tty有些类似于到实际所使用终端设备的一个链接/dev/tty0设备tty0表示的是当前虚拟控制台的一个别名,而实际的虚拟控制台是tty1…ttyn。其中tty1和tty2为X窗口系统,其余为虚拟字符原创 2021-01-07 22:04:27 · 2776 阅读 · 0 评论 -
如何查找x86-64平台上的内核堆栈位置
current宏在Linux 内核中负责获取当前cpu上的task_struct,通常是借助thread_info和内核栈实现我们需要先找到对应的内核栈,内核栈的栈底位置就是thread_info结构体:对于x86 64bit平台来说:DECLARE_PER_CPU(unsigned long, kernel_stack);212 213 static inline struct thread_info *current_thread_info(void)214 {215 struct原创 2021-01-07 10:42:25 · 725 阅读 · 0 评论 -
soft lockup的分类和定位方法
我之前已经写了lockup问题的检测原理,https://blog.csdn.net/rikeyone/article/details/112004920,本来就来尝试梳理一下soft lockup问题触发场景和解决方法。首先需要明确一点soft lockup是一类问题,引起它的原因也是各有不同,本文只是尝试做一些梳理,把一些具有共通性的特点的问题做一些总结,可能存在有不全面的地方。第一种场景:spinlock死锁场景对于这种场景,其实很好理解,当A-B/B-A死锁发生的时候,两个进程分别去获取对方持原创 2021-01-07 10:33:58 · 1203 阅读 · 0 评论 -
crash中如何查看gs寄存器中的值
gs寄存器在x86平台上主要用于记录per cpu变量的base address,我们可以使用kmem -o命令来查看这个基地址:crash> kmem -oPER-CPU OFFSET VALUES: CPU 0: ffff88013e800000 CPU 1: ffff8820f0c00000 CPU 2: ffff88013e820000 CPU 3: ffff8820f0c20000 CPU 4: ffff88013e840000 CPU 5: ffff8820f0原创 2021-01-06 16:46:03 · 1039 阅读 · 0 评论 -
汇编test %rax %rax的含义
x86平台上使用汇编如何判断一个值是否为0?一般会使用该指令:test %rax %raxje xxxtest指令会判断后面两个操作数执行AND操作,结果为0就设置zero flag,然后搭配je跳转指令从而实现对一个值是否为0的判断。如果%rax值为0,那么他们相与才会等于0,否则该值不会为0....原创 2021-01-05 20:02:46 · 6962 阅读 · 0 评论 -
CVM抖动问题分析思路
抖动是一个极其复杂的问题,它涉及到的原因非常多,本文试图理一下排查的思路,可能并不能涵盖所有内容。1.对于虚拟机来说,引起抖动的问题可能发生在虚拟机内部或者发生在宿主机上,那么第一步就是要先找出这个问题机器。比如网络抖动,那么直接就分别在宿主机和虚拟机中进行抓包来找出问题机器,定位到问题机之后再进一步查看。2.针对抖动问题,首先就是要抓到现场的数据,抖动一般都是比较短暂时间出发的行为,因此需要比较细粒度的trace方法常用的有atop、perf record等等3.引起抖动问题的因素有多种,需要一原创 2021-01-05 11:30:25 · 441 阅读 · 0 评论 -
soft lockup和hard lockup的检测原理
对于lockup问题处理,首先需要明确什么是lockup?它在什么情况下会被触发?本来就来聊聊这两种lockup是怎么检测的。soft lockup内核在每个CPU上都启动了一个watchdog线程,该线程被定期唤醒并记录per cpu的时间戳,同时启动的还有per-cpu的hrtimer,当hrtimer中断到来时会触发中断处理,在中断处理函数中会读取当前时间戳并与watchdog线程记录的时间做比较,如果两者相差超过一定范围(可以配置的watchdog_thresh)就会触发soft lockup异原创 2020-12-31 16:35:15 · 2121 阅读 · 1 评论 -
从kprobe注销场景来探讨一下synchronize_sched的使用
首先抛出我的问题:当我在编译一个kprobe内核插桩模块时,我是这样实现的,先动态申请一块内存,用于存放我的kprobe结构体,然后执行kprobe的注册,完成一系列的内核数据收集之后,执行kprobe注销操作,最后释放内存,那么大家觉得我这个设计有问题吗?对于初学者可能觉得:没有什么问题呀?kprobe有注册和有注销,内存有申请有释放,怎么出问题的,实际上正确答案就是没有问题。。。哈哈,是不是感觉被我忽悠了一下。下面我来说说我当时的顾虑,由于我是动态申请的内存,kprobe机制是这样的,注册了对应k原创 2020-09-02 22:15:37 · 557 阅读 · 0 评论 -
为何used内存占用很大,但是在meminfo中找不到?
服务器上使用free查看内存使用情况,发现如下: total used free shared buff/cache availableMem: 250G 31G 196G 41M 22G 217GLow: 250G 54G 196GHigh: 0B原创 2020-09-02 19:40:31 · 1554 阅读 · 0 评论