《Linux内核设计与实现》CHAPTER18阅读梳理

【学习时间:2hours】

【学习内容:bug的来源分析;bug调试途径】

一、bug来源

1.内核中的bug

  1. 内核中的bug表现得不像用户级程序中那么清晰——因为内核、用户以及硬件之间的交互会很微妙;
  2. 从隐藏在源代码中的错误到展现在目击者面前的bug,往往是经历一系列连锁反应的事件才可能触发的。

bug二、调试方法

1.通过打印来调试

  1. 优势:
    1. 健壮性是printk()函数最容易让人们接受的一个特质(使用环境和时机很广泛);
    2. printk()函数变体——early-printk()函数,区别仅在于可以更早(甚至在启动初期,终端还没有初始化之前)地工作
  2. 与printf()的区别
    1. printk()函数可以指定一个日志级别;内核更具指定级别与当前终端的等级console_loglevel来决定是否打印(只打印比当前终端等级低的消息);
    2. 终端默认的记录等级是KERN_WARNING
    3. 内核将最重要的记录等级KERNEMERG定为<0>;将无关紧要的记录等级KERNDEBUG定义为<7>
  3. 缓冲区
    1. 内核消息都被记录在环形队列中,以队列方式进行读写;大小可以通过设置CONFIGLOGBUF_SHIFT进行调整
    2. 在单处理器上,该缓冲区大小默认为16KB,也就是说,超过的消息将覆盖旧消息
    3. 优势:
      1. 读写同步问题容易解决
      2. 记录的维护更加方便
  4. 相关进程
    1. 用户空间的守护进程——klogd从记录缓冲区中读取内核信息,再通过syslogd守护进程将它们保存在系统日志文件中
      1. klogd会阻塞知道==直到有新的内核消息可供读出。被唤醒之后,它会读出新的内核消息并进行处理(默认情况下,就是传递给syslogd);
      2. syslogd会将所有接收到的消息添加到(默认情况下是messages)文件中

2.通过oops判断bug

  1. 概述

    • oops是内核告知用户有不幸发生的最常用方式(因为内核是整个系统的管理者,不能将自己杀死,也很难自行修复);
    • 通常,发送了oops之后,内核会处于不稳定的状态;如果oops在其他进程(除了0号idle和1号init进程)运行的时候发生,内核会杀死这些进程并尝试继续执行
  2. 信息
    • 回溯线索&寄存器上下文
      • 回溯消息展示了导致错误发生的函数调用链
      • 通过寄存器上下文中不正常的值可以判断哪个函数的变量出了问题
  3. 使用
    • 使用ksymoops
    • 将回溯线索中的地址转换成有意义的符号名称:
      • ksymoops saved_oops.txt
    • 使用kallsyms
    • 通过定义CONFIG_KALLSYMS配置选项启用,该选项中存放内核镜像中相应函数地址的符号名称,内核可以打印解码好的跟踪线索

3.内和调试配置项

  1. 配置项:CONFIGDEBUGKERNEL
  2. 选项 之 sleep-inside-spinlockchecking(自旋锁内睡眠选项)——正在使用自旋锁或者禁止抢占的代码进行的是原子操作,不可更改
  3. 探测范围:
    • 正在使用锁的时候调用schedule();
    • 正使用锁的时候以阻塞方式请求分配内存;
    • 引用单CPU数据时睡眠

4.引发bug并打印信息

  1. 利用BUG()以及BUG_ON()(因为大多数体系结构都把这两个函数定义成某种非法操作,可以触发oops)

    • 当做断言或者条件语句
  2. 调用panic()函数会在打印错误信息的同时挂起系统
    • panic("terrible thing",terrible_thing);
  3. 调用dump_stack(),只在终端上打印寄存器上下文及函数的跟踪线索

5.系统请求键

  1. 配置项:CONFIGMAGICSYSR配置选项来启动;此外,通过/proc/sys/kernel/sysrq标记该特性的开关
  2. 优点:无论内核处于什么状态,都可以通过特殊的组合键跟内核进行通信
  3. 常见的命令
    • SysRq-b:重启设备
    • SysRq-o:关闭机器
    • SysRq-u:卸载所有的文件系统
    • SysRq-s:把所有已安装的文件系统都刷新到磁盘

6.内核调试器

  1. 启动内核调试器

    • gdb vmlinux(未经压缩的内核映像)
  2. 反汇编函数
    • disassemble function(为什么要反汇编?因为有些执行文件无法获取到源代码,所以需要反汇编来获得代码,从而进行调试来查找问题)

7.探测系统

  1. 使用UID作为选择条件

    if(current->uid != 7777)
    {
    /*老算法*/
    else
    {
    /*新算法*/
    }
  2. 使用条件变量
  3. 使用统计量
  4. 重复频率限制
    1. 每隔几秒钟执行几次打印
    2. printk_ratelimit()函数
      • 默认情况下,此函数每隔5秒钟执行产生一次信息
    3. 实现发生次数限制
  5. 使用Git进行二分搜索

课堂内容总结

1.操作系统启动之后,开始的init与shell都只是普通程序

2.为什么系统调用后再调度?

系统调用咋返回用户态之后需要确定要返回哪个用户进程

3.Makefile的参数?

一共有4个:all,rootfs,.c.o,clean

总结

本章讲的虽然是“调试”,但并不只是debug;而是从系统的错误出发,探寻如何“解决”这些错误、从哪里寻求线索。我自己调试错误的经常使用的就是printk()以及debug()。

《Linux内核设计与实现》CHAPTER18阅读梳理的更多相关文章

  1. 《linux内核设计与实现》阅读笔记-进程与调度

      一.进程 process: executing program code(text section) data section containing global variables open f ...

  2. 《Linux内核设计与实现》CHAPTER17阅读梳理

    <Linux内核设计与实现>CHAPTER17阅读梳理 [学习时间:3.5hours] [学习内容:设备类型,模块,内核对象,sysfs] 个人思考部分见[]标出的部分 一.课堂讲解整理& ...

  3. 《Linux内核设计与实现》CHAPTER4阅读梳理

    <Linux内核设计与实现>CHAPTER4阅读梳理 [学习时间:3hours] [学习内容:多任务:进程调度策略:Linux中进程调度的关键问题:抢占] 个人思考部分见[]标出的部分 一 ...

  4. 《Linux内核设计与实现》CHAPTER5阅读梳理

    <Linux内核设计与实现>CHAPTER5阅读梳理 [学习时间:2.5hours] [学习内容:系统调用的概念.功能及实现:系统调用的创建和使用方法] CHAPTER5 系统调用 1.系 ...

  5. 《Linux内核设计与实现》CHAPTER1,2阅读梳理

    <Linux内核设计与实现>CHAPTER1,2阅读梳理 [学习时间:2.5hours] [学习内容:Linux内核简介——历史与现今版本:Linux内核源代码以及编译] CHAPTER1 ...

  6. 《Linux内核设计与实现》CHAPTER13阅读梳理

    <Linux内核设计与实现>第13章阅读总结 [edited by 5216lwr] 一.虚拟文件系统概述 1.虚拟文件系统 (也称作虚拟文件交换或VF)作为内核子系统,为用户空间程序提供 ...

  7. linux内核设计与实现一书阅读整理 之第三章

    chapter 3 进程管理 3.1 进程 进程就是处于执行期的程序. 进程就是正在执行的程序代码的实时结果. 内核调度的对象是线程而并非进程. 在现代操作系统中,进程提供两种虚拟机制: 虚拟处理器 ...

  8. linux内核设计与实现一书阅读整理 之第十八章

    CHAPTER 18 调试 18.1 准备开始 需要的是准备是: - 一个bug - 一个藏匿bug的内核版本 - 相关内核代码的知识和运气 重点: 想要成功的进行调试,就取决于是否能让这些错误重现. ...

  9. linux内核设计与实现一书阅读整理 之第五章

    CHAPTER 5 系统调用 5.1 与内核通信 系统调用在用户空间进程和硬件设备之间添加了一个中间层,该层主要作用有三个: 为用户空间提供了一种硬件的抽象接口 系统调用保证了系统的稳定和安全 每个进 ...

随机推荐

  1. storm 原理简介及单机版安装指南——详细版【转】

    storm 原理简介及单机版安装指南 本文翻译自: https://github.com/nathanmarz/storm/wiki/Tutorial 原文链接自:http://www.open-op ...

  2. NOI OpenJudge 8469 特殊密码锁 Label贪心

    描述 有一种特殊的二进制密码锁,由n个相连的按钮组成(n<30),按钮有凹/凸两种状态,用手按按钮会改变其状态. 然而让人头疼的是,当你按一个按钮时,跟它相邻的两个按钮状态也会反转.当然,如果你 ...

  3. js的BOM对象完全解析

    BOM即浏览器对象模型,它包括如下一些对象! (一)screen对象,Screen 对象中存放着有关显示浏览器屏幕的信息. 常见的属性有: availHeight:返回显示屏幕的高度 availWid ...

  4. HDU 4722 Good Numbers(DP)

    题目链接 脑子有点乱,有的地方写错了,尚大婶鄙视了... 来个模版的. #include <iostream> #include <cstdio> #include <c ...

  5. 【bzoj3160】万径人踪灭 FFT

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=3160 我是一个傻叉 微笑脸 #include<bits/stdc++.h> #de ...

  6. [奇葩 bug]视图在 ipad5 上正常显示,在 iPad3上超出了边界

    一,问题分析 1.理论上 iPad 是按像素点排列的,可 iPad5为什么和 iPad3差别那么大??? 2.iPad3超出边界的视图,都有一个 leading 是superview 的 leadin ...

  7. Js C# 实现跨域访问数据

    使用项目一的js调用项目二的数据 1.项目一 @{ Layout = null; } <!DOCTYPE html> <html> <head> <meta ...

  8. SQL Server 插入数据后获得自增主键值

    通过SQLServer系统自带函数获取 String sql = "insert into goods values('" + TextBox1.Text + "',&q ...

  9. DataGridView 中添加CheckBox和常用处理方式 .

    DataGridView 中添加CheckBox和常用处理方式 文章1 转载:http://blog.csdn.net/pinkey1987/article/details/5267934 DataG ...

  10. 转自:C#中TextBox水印提示的简单实现

    本文转自: 原作者: js2854 出处: http://js2854.cnblogs.com/ 本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接 ...