首页 > 系统相关 >linux ops panic 解析和定位

linux ops panic 解析和定位

时间:2024-04-02 14:57:31浏览次数:30  
标签:ops die 打印 信息 oops linux tryv1 bit panic

一、oops输出解析

https://zhuanlan.zhihu.com/p/680156398

Oops 信息包含以下几部分内容:

  • 一段文本描述信息,比如类似“Unable to handle kernel NULL pointer dereference at virtual address 00000000”的信息,它说明了发生的是哪类错误。
  • Oops 信息的序号,比如是第 1 次、第 2 次等。这些信息与下面类似,中括号内的数据表示序号。Internal error: Oops: 805 [#1]
  • 内核中加载的模块名称,也可能没有,以下面字样开头。Modules linked in:
  • 发生错误的 CPU 的序号,对于单处理器的系统,序号为 0,比如:CPU: 0Not tainted (2.6.22.6 #36)
  • 发生错误时 CPU 的各个寄存器值。
  • 当前进程的名字及进程 ID,比如:Process swapper (pid: 1, stack limit = 0xc0480258)这并不是说发生错误的是这个进程,而是表示发生错误时,当前进程是它。错误可能发生在内核代码、驱动程序,也可能就是这个进程的错误。
  • 栈信息。
  • 出错指令附近的指令的机器码,比如(出错指令在小括号里)
Code: e24cb004 e24dd010 e59f34e0 e3a07000 (e5873000)

栈回溯信息,可以从中看出函数调用关系,形式如下:

Backtrace:
[<c001a6f4>] (s3c2410fb_probe+0x0/0x560) from [<c01bf4e8>] (platform_drv_
probe+0x20/0x24)
...


(1)__die()

arch/arm64/kernel/traps.c
 
static int __die(const char *str, int err, struct pt_regs *regs)
{
	static int die_counter;
	int ret;
 
	pr_emerg("Internal error: %s: %x [#%d]" S_PREEMPT S_SMP "\n",
		 str, err, ++die_counter);
 
	/* trap and error numbers are mostly meaningless on ARM */
	ret = notify_die(DIE_OOPS, str, regs, err, 0, SIGSEGV);
	if (ret == NOTIFY_STOP)
		return ret;
 
	print_modules();
	show_regs(regs);
 
	dump_kernel_instr(KERN_EMERG, regs);
 
	return ret;
}

打印 EMERG 的log,Internal error: oops.....;

  • notify_die() 会通知所有对 Oops 感兴趣的模块并进行callback;
  • print_modules() 打印模块状态不为 MODULE_STATE_UNFORMED 的模块信息;
  • show_regs() 打印PC、LR、SP 等寄存器的信息,同时打印调用堆栈信息;
  • dump_kernel_instr() 打印 pc指针和前4条指令;

这里不过多的剖析,感兴趣的可以查看下源码。这里需要注意的是 notify_die() 会通知所有的Oops 感兴趣的模块,模块会通过函数 register_die_notifier() 将callback 注册到全局结构体变量 die_chain 中(多个模块注册进来形成一个链表),然后在通过 notify_die() 函数去解析这个 die_chain,并分别调用callback:

 

panic_print 默认值为 0,可以通过 /proc/sys/kernel/panic_print 节点配置,当 panic 发生的时候,用户可以通过如下bit 位配置打印系统信息:

  • bit 0:打印所有的进程信息;
  • bit 1:打印系统内存信息;
  • bit 2:打印定时器信息;
  • bit 3:打印当 CONFIG_LOCKEDP 打开时的锁信息;
  • bit 4:打印所有 ftrace;
  • bit 5:打印串口所有信息;

三、linux内核异常常用分析方法

  1. 异常地址是否在0附近,确认是否是空指针解引用问题
  2. 异常地址是否在iomem映射区,确认是否是设备访问总线异常问题,如PCI异常导致的地址访问异常
  3. 异常地址是否在stack附近,如果相邻,要考虑是否被踩
  4. 比较delay reset/nmi watchdog等多种机制打印的栈信息,看看pc是否在动,确定是否是死锁
  5. 用SysRq判断是真死还是假死
  6. 通过反汇编获得发生异常的C代码段和函数,查找开源社区是否已有补丁修复

下面分别通过PowerPC和Mips64的2个异常例子详细讲解分析过程。

 

二、工具

1、objdump

嵌入式环境下  ${CROSS_COMPILE}objdump -dS <path/to/kernel-src/>/vmlinux > vmlinux.disas


//查看地址
#grep oops_tryv1 /proc/modules
oops_tryv1 24576 1 - Loading 0xffffffffc0223000 (OE+)
//使用地址
#objdump -dS --adjust-vma=0xffffffffc0223000 ./oops_tryv1.ko > oops_tryv1.disas

 

  • RIP的地址0x88
  • ffffffffc071b000 + 0x88 = ffffffffc071b088
  • 即可看到出问题的地方*(int *)val = 'x';

2、gdb

# gdb -q ./oops_tryv1.ko
Reading symbols from ./oops_tryv1.ko...
(gdb) list *try_oops_init+0x88
0x12f is in try_oops_init (/home/wy/misc/kernel/Linux-Kernel-Debugging/ch7/oops_tryv1/oops_tryv1.c:60).

 

3、addr2line       

addr2line -e </path/to/>vmlinux -p -f <faulting_kernel_address>

addr2line -e ./oops_tryv1.o -p -f 0x88

4、decodecode


# /kernel/linux-5.15/scripts/decodecode < dmesg_oops_buginworkq.txt

 

 

 

5、faddr2line

usage: faddr2line [--list] <object file> <func+offset>

#grep CONFIG_RANDOMIZE_BASE /boot/config-5.15.0-47-generic

CONFIG_RANDOMIZE_BASE=y
# <>/scripts/faddr2line ./oops_tryv1.ko try_oops_init+0x88
try_oops_init+0x88/0x100:
try_oops_init at <...>/oops_tryv1/oops_tryv1.c:58

 

标签:ops,die,打印,信息,oops,linux,tryv1,bit,panic
From: https://www.cnblogs.com/ycjstudy/p/18108861

相关文章

  • Linux
    Linuxwc统计列数wc选项目标文件字符意思-l统计行数-w统计单词个数-c统计字节数grep过滤文本中你感兴趣的内容grep选项匹配式文件名或标准输入选项-i查找时忽略大小写-v反向查找,输出与查找条件不相符的行-o只......
  • Linux Red Hat重置密码和修改GRUB密码
    前言我们在使用Linux红帽的过程中可能会忘记root密码,很多小伙伴可能会重装红帽,接下来介绍两种省时省力又简便的方法。修改GRUB密码在重置密码之前我们需要注意两点,第一点是GRUB界面我们有时间限制,有些小伙伴可能还没反应过来就已经进入登录界面,所以我们需要修改相关的配置文......
  • Linux下创建root/普通用户
    1.Linux下创建root用户Ubuntu默认没有root用户,需要为其创建root用户,方法如下:sudopasswdroot:输入当前用户密码,然后输入root用户的密码,即可创建完成。切换到root用户的方法为:su-或su-root:输入root用户的密码即可登录,退出输入exit临时获取root用户权限su......
  • 监听 watch props对象属性监听 或深度监听
    对象属性监听 props:{baseFormObj:Object,},watch:{'baseFormObj.measuresItems':{immediate:true,//如果需要组件创建时立即监听,设置为truehandler(newVal,oldVal){//当myProperty变化时,这里的代码会被执行}......
  • MySQL-linux安装-万能RPM法
    一、MySQL的Linux版安装1、CentOS7下检查MySQL依赖1.检查/tmp临时目录权限(必不可少)由于mysql安装过程中,会通过mysql用户在/tmp目录下新建tmp_db文件,所以请给/tmp较大的权限。执行:chmod-R777/tmp2.安装前,检查依赖rpm-qa|greplibaiorpm-qa|grepnet-tools......
  • Linux 中新建用户和组
    查看当前登录账号:whoami`who`命令在Linux系统中用于显示当前登录到系统的用户信息。这些信息包括用户ID、终端类型、登录来源、登录时间、空闲时间、CPU使用情况和用户活动等。所有用户都可以使用这个命令来查看系统上的登录情况。  查看当前用户的userid和groupid......
  • 【攻防技术系列】 linux没有curl / wget如何实现下载功能 ( 测试成功版 )
    最近在分析挖矿木马,发现挖矿木马在入侵后都会对系统自带的部分命令进行替换或劫持。最常见的就是将wget和curl命令重命名。在多个挖矿木马同时竞争的情况下,没有wget和curl该如何远程下载挖矿脚本呢?直接看挖矿脚本是如何实现的。这里面涵盖了很多知识点,非常值得学习!funct......
  • linux中新建、删除、赋权限文件
    新建文件(非目录)touch新建一个空文件,如果文件已存在,则只更新其访问时间和修改时间。使用echo命令,并通过重定向将输出内容写入到一个新文件中,这样可以创建一个空文件,如果文件已存在则会覆盖之前内容。使用vi文本编辑器可以打开文件进行编辑,如果文件不存在则会新建新建的文......
  • Linux研究(6):Linux 硬链接和软连接-详解
    导言:当涉及到Linux文件系统中的链接时,有两种常见类型:硬链接(HardLink)和软链接(SymbolicLink,也称为符号链接或软连接)。它们用于在文件之间创建关联,提供了一些非常有用的功能。下面是对硬链接和软链接的详细解释以及一个实验样例。1.硬链接(HardLink)硬链接是通过文件系统......
  • Linux enable命令教程:启动或关闭shell内建指令(附实例详解和注意事项)
    Linuxenable命令介绍enable是Linux系统中的内建命令,用于启动或关闭shell内建指令。如果执行的文件名称与shell内建指令相同,可以使用enable-n来关闭shell内建指令。如果不加-n参数,enable可以重新启动已关闭的指令。Linuxenable命令适用的Linux版本enable命令在大多数Li......