Linux系统崩溃有kdump机制来记录,但是由于kdump的文件内容一般很大,在嵌入式系统一般不使用,嵌入式系统一般使用把printk重定位到黑匣子中的方法来记录异常,另外还需要其他的故障检测方法来完善系统所有场景下的异常检测。

除了系统的一些通用方法,我们在定位系统死机、复位故障时需要更多的手段来搜集信息,一般嵌入式系统采取的手段有:

  • 1、创建内存、flash黑匣子,把故障点、函数调用栈等信息在复位之前记录到黑匣子,以供第二次复位起来以后分析;
  • 2、在各种可能产生复位的地方,包括各种主动复位和被动复位的地方(如:panic、reboot、按键复位、看门狗复位)加上钩子函数,记录下具体的复位原因;
  • 3、一些主动监测死锁的手段。

1、printk黑匣子

在一些内核本身可以检测到的故障发生时,内核会陷入Panic、die、BUG_ON等函数,打印出故障定位信息和调用栈信息。

对于这一类的系统复位问题,除了kdump机制把系统内存信息记录下来以外,另一个可行的方法就是查看复位前的printk内核打印信息, 所以获得上一次复位前的printk信息对定位这一类问题非常有用,系统本身是通过klog和syslog进程记录printk信息到日志,但是在系统崩溃时这种机制不能保证信息能被记录下来。

通常的做法是定制黑匣子来记录printk信息,具体的原理就是保留一段系统热复位不会被清除的内存,注册一个新的console,printk信息会被多复制一份到黑匣子内存中。系统重启以后再把内存黑匣子中的信息转储到磁盘。

上图是系统保留内存的使用分布图,其中section PRINTK1和section PRINTK2部分被分配给printk黑匣子使用。

下面看一下具体的代码实现:


1.1、printk保留内存

1.2、注册console

注册console的主要目的是将printk打印,打印一份到保留内存的当前内存中去。




1.2.1、Kbox_DumpPanicInfor()

除了通过g_stPrintkConsole打印printk信息到printk黑匣子区域,还可以通过Kbox_DumpPanicInfor()和kbox_dump_printf ()直接打印内容到printk黑匣子区域。同时会打印内容到panic info区域的缓存g_aucSysLogBuf。

1.2.2、kbox_dump_printf ()

1.3、注册proc文件

注册proc文件的主要目的是将保留内存的上一次内存中的打印信息通过proc文件呈现。






2、dump设备

为了定位系统的异常原因,我们在各种异常处理的函数中注册自己的钩子函数,在出现异常时把定位信息dump到黑匣子设备中。

2.1、ram dump设备

系统的保留内存除了其中两块区域给printk重定向使用以外,还有其他的区域注册成字符设备,给dump信息使用。

上图是系统保留内存的使用分布图,其中:

  • section PRINTK1和section PRINTK2部分被分配给printk黑匣子使用;
  • section KERNEL被分成两部分记录panic info和thread info,分别使用Kbox_OutputDumpLog()和Kbox_DumpThreadInfor ()函数来呈现;
  • section USER记录用户态的数据,通过字符设备的ioctl接口开放给用户使用;
  • section ALL包括所有的KERNEL、PRINTK1、PRINTK2、USER区域,通过字符设备的read()、write()接口提供给用户访问。






2.1.1、stRamDevOp->pfnDevInit()

stRamDevOp->pfnDevInit ()在字符设备初始化函数KBox_RegisterDev()中被调用。



2.1.2、stRamDevOp-> pfnImgInit()

stRamDevOp-> pfnImgInit ()在字符设备初始化函数KBox_RegisterDev()中被调用。



2.1.3、stRamDevOp-> pfnImgInitWritePanicInfo()

stRamDevOp-> pfnImgInitWritePanicInfo ()在Kbox_WriteDumpLogToDev ()中被调用。



2.1.4、tRamDevOp-> pfnImgWritePanicInfo()

stRamDevOp-> pfnImgWritePanicInfo ()在Kbox_WriteDumpLogToDev ()中被调用。


2.1.5、stRamDevOp-> pfnImgWriteThreadInfo()

stRamDevOp-> pfnImgWriteThreadInfo ()在Kbox_WriteThreadInfor ()中被调用。



2.1.6、stRamDevOp-> pfnUserRegionOp()

stRamDevOp-> pfnUserRegionOp ()在KBOX_IOCtrl ()中被调用,用于用户态记录信息到section USER保留内存中。











2.1.7、stRamDevOp-> pfnWrite()

stRamDevOp-> pfnWrite ()在Kbox_Write ()中被调用,是字符设备真正的写函数。





2.1.8、stRamDevOp-> pfnRead()

stRamDevOp-> pfnRead ()在Kbox_Read ()中被调用,是字符设备真正的读函数。




2.2、flash dump设备

flash dump设备和ram dump设备的原理相同,只是记录的信息更少,这里就不详细解析。

2.3、panic info缓存

系统创建了一个临时panic info缓存即g_aucSysLogBuf,在需要刷新的时候才会把缓存内存刷新到ram、flash dump设备的panic info区域当中。一方面会把它注册成consle用来存储printk信息,另一方面也可以直接调用接口向缓存中打印。

2.3.1、注册console()






可以看到console口实质就是把printk内容打到g_aucSysLogBuf缓存中。

2.3.2、Kbox_DumpPanicInfor()

除了通过g_stKboxConsole打印printk信息到g_aucSysLogBuf缓存,还可以通过Kbox_DumpPanicInfor()和kbox_dump_printf ()直接打印内容到g_aucSysLogBuf缓存中。同时会打印内容到printk黑匣子区域。

2.3.3、kbox_dump_printf()

2.3.4、panic info dump

Kbox_OutputDumpLog负责将panic info缓存g_aucSysLogBuf中的数据刷新到真正的设备panic info区域中,并产生一条新的panic info记录。



2.4、thread info dump

Kbox_DumpThreadInfor()函数用来写入数据到设备的thread info区域。



Kbox_WriteThreadInforToDev()通过调用KBOX_PRINTK()来调用Kbox_DumpThreadInfor(),打印具体的线程信息到设备thread info区域。









3、异常dump

为了定位系统的异常原因,我们在各种异常处理的函数中注册自己的钩子函数,在出现异常时把定位信息dump到黑匣子设备中。

3.1、kbox_netnf_init()

注册网卡事件的钩子函数,在网卡up、down时通过printk打印日志,dump内核调用栈和进程间调用关系。





3.2、KBOX_RegisterPanicHook ()







3.3、KBOX_RegisterRebootHook ()







3.4、KBOX_RegisterMRestartHook()






3.5、KBOX_RegisterSecurityHook ()











3.6、KBOX_RegisterKprobeHook ()

3.6.1、stJpPanic

3.6.2、stJpButton




3.6.3、stJpMceError




3.6.4、ip、路由等事件监控



3.7、KBOX_RegisterBmcResetHook()

注册钩子函数来响应bmc的复位预中断。










3.8、KBOX_RegisterDogMonHook()

创建看门狗的监控进程,在看门狗复位之前预先记录信息。







3.9、Oom钩子函数

Oom全称out of memory即为系统内存耗尽,在系统本身的oom处理中,系统会杀死一些进程来缓解内存耗尽的情况。


在嵌入式系统中,如果出现oom估计也没有可以挽救的机会聊,可以在oom的钩子函数中注册自己的oom处理策略,直接panic系统。










4、死锁检测

除了系统可以自己侦测到的故障,很多故障是系统自己无法检测到的,在smp系统中我们可以使用多个cpu来相互检测异常,检测进程挂死的异常。








4.1、cpu死锁





4.2、进程死锁






“task->last_ran”任务最后一次运行时间戳是在任务调度函数schedule()中被设置的:

[monitor] 7. Linux几种内核故障定位方法相关推荐

  1. Linux 驱动的内核适配 - 方法

    原生与野生 Linux 的驱动代码大致可分为两种:一种是已经进入 mainline 的,当内核 API 变化时,会被同步地修改:还有一种是 out-of-tree 的,需要用一套驱动代码去适配不同版本 ...

  2. linux历史版本内核下载方法。

    光从官网上找到的是没有历史版本的直接下载选项的,只有通过终端或者采用输入网址的方法才能得到. 直接将后面内核的版本号修改即可. 修改方法: 1. 查看linux内核版本号: uname -a 2. 对 ...

  3. Linux CentOS7 升级内核的方法

    0.查看操作系统内核版本 [root@host-10-20-89-5 default]# uname -r 1.安装ELRepo到CentOS 最好从官方网站获取最新版本(官网地址:http://el ...

  4. 锤子手机安装 linux,两种锤子系统安装方法【图文详解】

    很多用安卓手机的人都知道"锤子"系统界面和其他 苹果 和安卓系统的界面是不一样的,"锤子"系统界面应用在安卓手机上显示的是重新画的应用图标.整体上还是很好看的, ...

  5. grub2引导linux内核,一种基于grub2的linux系统启动bootloader的制作方法与流程

    技术领域 本发明涉及服务器应用技术领域,具体涉及一种基于grub2的linux系统启动bootloader的制作方法. 背景技术: 当前linux系统的内核版本已经升级至4.0以上,最新的linux系 ...

  6. 申威 linux内核,一种申威防火墙快速移植高版本linux内核的方法与流程

    技术特征: 1.一种申威防火墙快速移植高版本linux内核的方法,其特征在于,包括以下步骤: s1:预先制作生成内存根文件系统的压缩文件: 所述步骤s1包括以下步骤: s11:通过编译busybox制 ...

  7. Linux centos7升级内核(两种方法:内核编译和yum更新)

                Linux centos7升级内核(两种方法:内核编译和yum更新) Linux的内核概念不用说大家也很清楚,正是内核版本的不同,才有Linux发行版本的说法,现在主流的cen ...

  8. linux 故障注入_用软件中断实现的Linux内核故障注入方法

    用软件中断实现的 Linux 内核故障注入方法 郭庆伟 ; 杨麦顺 ; 张影 ; 张兴军 [期刊名称] <计算机应用> [年 ( 卷 ), 期] 2014(000)0z2 [摘要] 针对容 ...

  9. Linux内核调试方法总结【转】

    转自:http://my.oschina.net/fgq611/blog/113249 内核开发比用户空间开发更难的一个因素就是内核调试艰难.内核错误往往会导致系统宕机,很难保留出错时的现场.调试内核 ...

最新文章

  1. 102. Binary Tree Level Order Traversal
  2. 【Git笔记1】本地项目与GitHub远程仓库互联
  3. centos6.5安装python3.6
  4. 2005年7月19日
  5. 【生活相关】北京南苑机场接人
  6. 在线Javascript美化格式化工具
  7. 插头dp ——从入门到跳楼
  8. 惠普磁带备份机支持备份几台服务器,HP 磁带机和 Tapeware 备份软件
  9. python尔雅答案_2020尔雅通识课Python》程序设计查题公众
  10. IP协议详解【IP报文头部结构、IP分片、IP路由、IP转发】
  11. db4小波的一次分解与重构
  12. 马士兵—JVM—内存溢出—2.arthas阿里线上Java诊断工具
  13. 实现一个div的背景颜色从左到右慢慢出现
  14. 模拟登陆爬取大学智慧校园的成绩单
  15. linux训练python出现killed_linux命令总结(二)
  16. 二维火收银系统服务器超时,二维火收银系统,改变的不止是你的收银模式!
  17. python教程app 小米应用商店_Python爬虫过程解析之多线程获取小米应用商店数据...
  18. outlook显示服务器错误,Outlook,弹出登陆框,无法登陆 服务器错误0x800CCC90 错误号:0...
  19. 370A. Rook, Bishop and King codeforce题解
  20. java飞机大战护盾_全民飞机大战无敌护盾使用方法分享

热门文章

  1. 在标签打印软件中制作珠宝条码标签
  2. android 重力权限,Java-Android:设置RecyclerView项的重力
  3. SQL语句中删除表数据drop、truncate和delete的用法
  4. android aidl权限,Android AIDL
  5. laravel-admin表格table创建与展示
  6. KT404A/C系列语音芯片参考程序硬件设计注意事项
  7. 2012-IJCV - Non-uniform deblurring for shaken images
  8. java 建立索引_java中怎么创建索引
  9. Grafana 国内镜像源加速下载
  10. 技术分享连载(七十六)