Linux内核中的panic
目录
一、内核配置
二、程序触发panic
三、命令行执行触发panic
四、panic源码
解析panic
五、系统收到收到panic处理方式
六、编写自定义内核panic处理程序例程
1、内核中的使用
2、自定义处理函数示例
七、实例代码
一、内核配置
CONFIG_MAGIC_SYSRQ=y
二、程序触发panic
在内核中调用函数panic
panic("whoa, a kernel panic!");
三、命令行执行触发panic
命令行下执行
#设置内核panic
echo 1 > /proc/sys/kernel/panic_on_oops
#使能内核magic sysrq
echo 1 > /proc/sys/kernel/sysrq
#magic sysrq feature
echo c > /proc/sysrq-trigger
查看内核中sysrq,上述的c代表 crash
benshushu:~# echo ? > /proc/sysrq-trigger ;dmesg | tail -n1
[ 154.967245] sysrq: SysRq : HELP : loglevel(0-9) reboot(b) crash(c)
terminate-all-tasks(e) memory-full-oom-kill(f) kill-all-tasks(i) thaw-filesystems(j)
sak(k) show-backtrace-all-active-cpus(l) show-memory-usage(m) nice-all-RT-tasks(n)
poweroff(o) show-registers(p) show-all-timers(q) unraw(r) sync(s)
show-task-states(t) unmount(u) show-blocked-tasks(w) dump-ftrace-buffer(z)
四、panic源码
大部分省略
void panic(const char *fmt, ...)
{local_irq_disable();preempt_disable_notrace();pr_emerg("Kernel panic - not syncing: %s\n", buf);kgdb_panic(buf);kmsg_dump(KMSG_DUMP_PANIC);if (_crash_kexec_post_notifiers)__crash_kexec(NULL);pr_emerg("---[ end Kernel panic - not syncing: %s ]---\n", buf);/* Do not scroll important messages printed above */suppress_printk = 1;local_irq_enable();for (i = 0; ; i += PANIC_TIMER_STEP) {touch_softlockup_watchdog();if (i >= i_next) {i += panic_blink(state ^= 1);i_next = i + 3600 / PANIC_BLINK_SPD;}mdelay(PANIC_TIMER_STEP);}
}
解析panic
- 代码尽其所能避免复杂性和可能的死锁
- KERN_EMERG 内核打印信息 “Kernel panic - not syncing”
- panic_print_sys_info();确定并显示更多系统信息–例如所有任务信息、内存、计时器、锁、ftrace信息和所有内核打印。具体取决于panic_print的bitmask
- 函数所做的最后一件事就是在单个启用的处理器核上无限循环;在循环中,它重置非屏蔽中断(NMI),然后定期调用一个名为架构依赖的panic_blink函数;在x86上,该事件会引起键盘LED会闪烁,驱动drivers/input/serio/i8042.c:i8042_panic_blink().
五、系统收到收到panic处理方式
- 当内核kexec/kdump使能,进入dump-capture kernel状态
- 定制panic处理函数,除了常规的紧急处理代码之外,还会调用处理函数
- 当内核参数panic=n,表示panic持续时间,在n秒后重启
六、编写自定义内核panic处理程序例程
内核支持四种不同类型,基于回调函数执行的环境
- 原子的Atomic:函数运行在原子上下文,不能阻塞
- 阻塞Blocking:函数运行在进程上下文,可以阻塞
- 睡眠Sleepable RCU:函数运行在进程上下文,可以阻塞,免锁机制
- 原始Raw:在任何上下文中运行,可以或可以不阻塞
1、内核中的使用
- drivers/net/netconsole.c:netconsole_netdev_event()
- register_reboot_notifier()
2、自定义处理函数示例
原子的 注册函数,实际上对spin_lock_irqsave/spin_unlock_irqsave封装
// include/linux/notifier.h
struct notifier_block {notifier_fn_t notifier_call;struct notifier_block __rcu *next;int priority;
};
// kernel/panic.c
ATOMIC_NOTIFIER_HEAD(panic_notifier_list);
EXPORT_SYMBOL(panic_notifier_list);int atomic_notifier_chain_register(struct atomic_notifier_head*,struct notifier_block*);
int atomic_notifier_chain_unregister(struct atomic_notifier_head *nh, struct notifier_block *n);
1、从文件名可以知道,atomic原子操作,不能阻塞
2、注册 atomic_notifier_chain_register
3、注销 atomic_notifier_chain_unregister
七、实例代码
#define pr_fmt(fmt) "%s:%s(): " fmt, KBUILD_MODNAME, __func__
#include <linux/init.h>
#include <linux/module.h>
#include <linux/notifier.h>
#include <linux/delay.h>MODULE_LICENSE("Dual MIT/GPL");static void dev_ring_alarm(void)
{pr_emerg("!!! ALARM !!!\n");
}
//回调函数的实现
static int mypanic_handler(struct notifier_block *nb, unsigned long val, void *data)
{//打印参数pr_emerg("\n************ Panic : SOUNDING ALARM ************\n\
val = %lu\n\
data(str) = \"%s\"\n", val, (char *)data);//执行的函数dev_ring_alarm();return NOTIFY_OK;
}//结构体
static struct notifier_block mypanic_nb = {.notifier_call = mypanic_handler,//回调函数
// .priority = INT_MAX
};static int __init panic_notifier_init(void)
{//注册函数atomic_notifier_chain_register(&panic_notifier_list, &mypanic_nb);pr_info("Registered panic notifier\n");//延时500ms 并触发panicmdelay(500);panic("Linux Kernel Debugging!");return 0; /* success */
}static void __exit panic_notifier_exit(void)
{atomic_notifier_chain_unregister(&panic_notifier_list, &mypanic_nb);pr_info("Unregistered panic notifier\n");
}module_init(panic_notifier_init);
module_exit(panic_notifier_exit);
参考
https://course.0voice.com/v1/course/intro?courseId=2&agentId=0
Linux内核中的panic相关推荐
- 制造linux内核异常,了解Linux内核中的异常
我想在非常低的温度下调试我们的嵌入式Linux系统(< 40C).问题是,它并不总是正确启动,我试图找出原因.经过一番分析,我看到内核启动了下面的输出期间进入恐慌:了解Linux内核中的异常 c ...
- Linux内核中锁机制之完成量、互斥量
在上一篇博文中笔者分析了关于信号量.读写信号量的使用及源码实现,接下来本篇博文将讨论有关完成量和互斥量的使用和一些经典问题. 八.完成量 下面讨论完成量的内容,首先需明确完成量表示为一个执行单元需要等 ...
- 简单谈一点linux内核中套接字的bind机制--数据结构以及端口确定
众所周知,创建一个套接字可以bind到一个特定的ip地址和端口,实际上套接字这一概念代表了TCP/IP协议栈的应用层标识,协议栈中的应用层就是通过一个ip地址和一个端口号标识的,当然这仅仅是对于TCP ...
- Linux 内核中的 Device Mapper 机制
本文结合具体代码对 Linux 内核中的 device mapper 映射机制进行了介绍.Device mapper 是 Linux 2.6 内核中提供的一种从逻辑设备到物理设备的映射框架机制,在该机 ...
- 如何放出Linux内核中的链表大招
前言 上回,我们说到Linux内核中max()宏的终极奥义,Linux内核链表也不甘示弱,那么接下来,让我们看看Linux内核中的链表大招. 如何放出Linux内核中的链表大招 前言 一.链表简介 ( ...
- Linux内核中max()宏的奥妙何在?(一)
Linux内核中max()宏的奥妙何在?(一) 1.max()宏那点事 在Linux内核中,有这样四个比较大小的函数,如下: max(x,y) //两个数求最大值 min(x,y) //两个数求最小值 ...
- Linux内核中max()宏的奥妙何在?(二)——大神Linus对这个宏怎么看?
最新max()宏 上回,我们在<Linux内核中max()宏的奥妙何在?(一)>一文中说到,在3.18.34版Linux内核源码中的max()宏,采用了GCC的扩展特性,可以避免一些错误. ...
- Linux中文件描述符1,linux内核中的文件描述符(一)--基础知识简介
原标题:linux内核中的文件描述符(一)--基础知识简介 Kernel version:2.6.14 CPU architecture:ARM920T Author:ce123(http://blo ...
- Linux 内核中的 GCC 特性(zz)
from:http://www.ibm.com/developerworks/cn/linux/l-gcc-hacks/ GCC 和 Linux 是出色的组合.尽管它们是独立的软件,但是 Linux ...
最新文章
- 实践操作:六步教你如何用开源框架Tensorflow对象检测API构建一个玩具检测器
- 报名 | 大数据打造智慧的政府门户讲座
- 性能测试通过几种方式造数据
- 谷歌将采取自动化系统审核,预计被误删视频数量或将大增
- 【转】C# DateTime 日期计算
- Equipment upload - ERP ACK
- oryx-editor 客户端的加载过程
- 第五课 机器学习中的特征工程
- 那些你不知道的程序员的多重身份
- 发电机变压器运行状态(温度电压电流)监控系统解决方案
- 华为 USG6000防火墙管理员密码重置(配置会清空)
- 记Dorado7学习(5)
- word转换成pdf后图片压缩失真的解决方法
- mysql大于、小于符号的两种表示方法
- 个人计算机操作系统支持多用户多任务,windows10是一个多用户多任务操作系统吗...
- 计算机英语boot,电脑开不了机显示英文boottmgr
- 计算机大赛可以跨学校组队吗,大学生创新创业大赛可以跨校组队吗
- 关闭系统还原清理垃圾文件
- 视频相关的hls协议、VLC播放器、m3u文件的播放
- JDBC基本原理及使用
热门文章
- 【java华为机试】HJ10 字符个数统计
- python单词词典_Python自然语言处理学习笔记(42):5.3 使用Python字典将单词映射到属性...
- springboot启动时,排除某些自动配置类
- Linux下修改hostname的三种方式
- 双系统模式下如何卸载ubuntu系统
- 安装和删除Ubuntu双系统
- c语言 读取TXT 去空格,C语言读取TXT文件,忽略文件空格,把内容写入数组中应该如何实现...
- OLAP、OLTP的介绍和比较
- 动态规划!!!动态规划!!!
- Mocha Pro 2022(合集)