第十八章 调试


一、调试开始前的准备

1.准备开始

  • bug
  • 藏匿bug的版本
  • 相关内核代码的知识

  成功调试的关键在于能否将错误重现

2.内核中的bug

  其产生原因无数,表象变化也多种多样。从隐藏在源代码中的错误到出现的bug,可能是由一系列连锁反应触发的。

二、通过打印调试

1.健壮性

  printk()函数的健壮性特质使得任何时候、任何地方都能调用它。

  • 在中断上下文和进程上下中使用
  • 在任何持有锁被调用时
  • 在多处理器上同时被调用

2.日志等级

  printk()和printf()在使用上的最主要区别是前者可以指定一个日志级别,内核根据这个级别判断终端是否打印消息;

  KERN_WARNING和KERN_DEBUG都是<linux/kernel.h>中的简单宏定义,扩展开是<4>和<7>这样的字符串,加进printk()函数要打印的开头。

  内核将最重要的记录等级定为<0>,最无关紧要的记录等级定为<7>。

3.记录缓冲区

  • 记录消息被保存在一个环形队列中,读写按照环形队列方式进行操作
  • 内核在同一时间只能保存16KB的消息,当消息队列达到最大值,再有调用时,新消息将覆盖队列中的老消息。
  • 优点:同步问题很容易解决;记录维护也变得容易。
  • 缺点:可能会丢失消息

4.syslogd和klogd

  用户空间的守护进程klogd从记录缓存区中获取内核消息,再通过守护进程syslogd将它们保存在系统日志文件中。

三、oops

1.发布oops的过程

  包括向终端上输出错误消息,输出寄存器中保存的信息并输出可供跟踪的回溯线索。通常,发送完内核会处于不稳定状态。

2.导致结果

  如果发生在中断上下文时,内核会陷入混乱,系统死机;

  如果在idle或init进程时发生,系统同样会陷入混乱,缺失这两个进程,内核无法工作。

  如果在其他进程运行时发生,内核会杀死该进程并尝试继续执行。

3.发生原因

  内存访问越界或非法指令

4.包含的信息结构

  寄存器上下文和回溯线索

  • 回溯线索显示导致错误发生的函数调用链
  • 寄存器数据可以帮助重建引发问题现场

四、引发bug并打印信息

  BUG()和BUG_ON()是常用的标记bug的内核调用,被调用时,会引发oops,导致栈的回溯和错误信息的打印。

  用panic()引发更严重的错误,不但打印错误信息,还会挂起整个系统。

五、Magic SysRq Key

  当该功能被启用时,无论内核处于什么状态,都可通过特殊的组合键跟内核进行通信。

  • 使用定义CONFIG_MAGIC_SYSRQ配置选项和命令echo 1 > /proc/sys/kernel/sysyrq启用

六、内核调试器和系统探测

1.内核调试器

  • 可以使用标准的GNU内核调试器对正在运行的内核进行查看
  • 可以使用gdb的所有命令来获取信息

2.探测系统

  • 用UID作为选择条件,可以安排到底执行哪种算法
  • 使用条件变量,创建一个全局变量作为一个条件选择开关
  • 使用统计量,通过创建统计量提供某种机制访问其统计结果
  • 重复频率限制,用于某种事件发生频繁,又要观察它的整体情况。为避免信息发生井喷,可以每隔几秒执行一次打印。

七、二分查找法与GIT工具

1.当不知道哪个内核版本引入bug,但又确实存在使用二分法进行查找

  假定一个版本有问题,而另一个没有,从二者正中选择版本检查,从而缩小范围,以此类推。

2.使用GIT进行二分搜索

  如果使用GIT来控制Linux源码树的副本,那么它将自动进行二分搜索进程

  • 告诉GIT进行二分搜索

  $ git bisect start

  • 为GIT提供一个出现问题的最早内核版本

  $ git bisect bad <revision>

  • 提供一个最新的可正常运行的内核版本

  $ git bisect good 版本号

  这样,GIT将自动检测正常版本和有bug的版本哪个之间有隐患,接着再编译运行以及测试正被检测版本。

 

  

  

《Linux内核设计与实现》第18章读书笔记的更多相关文章

  1. 《Linux内核设计与实现》第四周读书笔记——第五章

    <Linux内核设计与实现>第四周读书笔记--第五章 20135301张忻 估算学习时间:共1.5小时 读书:1.0 代码:0 作业:0 博客:0.5 实际学习时间:共2.0小时 读书:1 ...

  2. LINUX内核设计与实现第三周读书笔记

    LINUX内核设计与实现第三周读书笔记 第一章 LINUX内核简介 1.1 Unix的历史 1969年的夏天,贝尔实验室的程序员们在一台PDR-7型机上实现了Unix这个全新的操作系统. 1973年, ...

  3. 《Linux内核设计与实现》Chapter 3 读书笔记

    <Linux内核设计与实现>Chapter 3 读书笔记 进程管理是所有操作系统的心脏所在. 一.进程 1.进程就是处于执行期的程序以及它所包含的资源的总称. 2.线程是在进程中活动的对象 ...

  4. 《Linux内核设计与实现》Chapter 1 读书笔记

    <Linux内核设计与实现>Chapter 1 读书笔记 一.Unix的特点 Unix从Multics中产生,是一个强大.健壮和稳定的操作系统. 特点 1.很简洁 2.在Unix系统中,所 ...

  5. 《Linux内核设计与实现》Chapter 2 读书笔记

    <Linux内核设计与实现>Chapter 2 读书笔记 一.获取内核源码 1.使用Git 我们曾经在以前的学习中使用过Git方法 $ git clone git://git.kernel ...

  6. 《Linux内核设计与实现》Chapter 5 读书笔记

    <Linux内核设计与实现>Chapter 5 读书笔记 在现代操作系统中,内核提供了用户进程与内核进行交互的一组接口,这些接口的作用是: 使应用程序受限地访问硬件设备 提供创建新进程与已 ...

  7. Linux内核设计与实现第十周读书笔记

    第十七章 设备与模块 关于设备驱动与设备管理,我们讨论四种内核成分. 设备类型 模块 内核对象 sysfs 17.1设备类型 在Linux以及所有Unix系统中,设备被分为以下三种类型: 块设备,块设 ...

  8. Linux内核设计与实现第五周读书笔记

    第十八章 调试 18.1准备开始 需要的只是: 一个确定的bug.大部分bug通常都不是行为可靠而且定义明确的. 一个藏匿bug的内核版本. 相关的内核代码的知识和运气. 18.2内核中的bug 内核 ...

  9. Linux内核设计与实现第八周读书笔记

    第四章 进程调度 进程在操作系统看来是程序的运行态表现形式. 4.1多任务 多任务操作系统就是能同时并发地交互执行多个进程的操作系统. 多任务操作系统会使多个进程处于堵塞或者睡眠状态.这些任务尽管位于 ...

  10. Linux内核设计与实现第六周读书笔记

    第三章 进程管理 3.1 进程 进程是处于执行期的代码.通常进程还要包含其他资源,像打开的文件.挂起的信号.内核的内部数据.处理器状态.一个或多个具有内存映射的内存地址空间及一个或多个执行线程,当然还 ...

随机推荐

  1. webpack3升级为webpack4

    写在前面的话:为什么要升级,因为公司目前的项目使用webpack3,但是因为是多页应用,入口估计有一百多个,开发模式下慢得不像话,修改一个文件需要十几秒才编译好,之前的解决方案是减少入口,但是要调试其 ...

  2. Java中final与 static final 修饰的常量的区别

    喵喵开车,新手上路,多多关照.有任何错误请在评论区指出. ...........................................我是万恶的分界线( • ̀ω•́ )✧......... ...

  3. RHEL7 利用双网卡绑定实现VLAN

    使用nmcli创建bond配置 #nmcli connection add type bond ifname bond0 con-name bond0 mode active-backup #nmcl ...

  4. 持续更新 | 想不到的key

    前言 开坑写一些我认为比较巧妙的东西想不到的东西 正文 判断回文串的时候 考虑一下枚举中心位往两边扩展 最大子矩阵与单调栈 遇难则反系列 算合法可以转换成算不合法.同理,不合法转换成合法计算有时也会简 ...

  5. BP神经网络算法推导

    目录 前置知识 梯度下降法 激活函数 多元复合函数求偏导的相关知识 正向计算 符号定义 输入层 隐含层 输出层 误差函数 反向传播 输出层与隐含层之间的权值调整 隐含层与输入层之间权值的调整 计算步骤 ...

  6. Java面试中的Spring方面问题

    1.一般问题 1.1. 不同版本的 Spring Framework 有哪些主要功能? VersionFeatureSpring 2.5发布于 2007 年.这是第一个支持注解的版本.Spring 3 ...

  7. 使用 PropTypes 进行类型检查

    注意: 从 React v15.5 开始 ,React.PropTypes 助手函数已被弃用,建议使用 prop-types 库 来定义contextTypes. 1 2 3 4 5 6 7 8 9 ...

  8. fs - 文件系统

    fs 模块提供了一些 API,用于以一种类似标准 POSIX 函数的方式与文件系统进行交互. 用法如下: const fs = require('fs'); 所有的文件系统操作都有异步和同步两种形式. ...

  9. ffmpeg——压缩mav格式音频

    今天偶然帮朋友压缩一个mav格式的音频.开始用压缩码率的方式,mav格式的音频体积一点都没变,查资料需要压缩音频文件的采样率和声道才能压缩mav格式的音频. 压缩要求是:将一个mav格式的音频文件,由 ...

  10. Aspose.words Java基于模板生成word之循环图片

    1.新建一个word文档 2.给插入图片的地方设置书签 3,设置书签 二,项目 1,2步的引入依赖以及加载授权文件同上一篇 3,获取图片路径插入到word中并生成新的word文档 新文档中,每行显示两 ...