一、准备开始

1、一个确定的bug,但大部分bug通常都不是行为可靠且定义明确的。

2、一个藏匿bug的内核版本。

3、相关内核代码的知识和运气。

二、内核中的bug

1、bug的表象:

明白无误的错误代码,同步时发生的错误,错误地管理硬件,降低所有程序的运行性能,毁坏数据,使系统处于死锁状态。

2、引用空指针会导致产生一个oops,垃圾数据可能会导致系统崩溃。

三、通过打印来调试

1、printk()是内核的格式化打印函数,与C库提供的printf()函数功能基本相同。

2、printk()在任何时候、任何地方都能调用它。除了系统启动过程中,终端还没有初始化之前,在某些地方不能使用它。

early_printk()在启动过程的初期就具备在终端上打印的能力,但缺少可移植性。

3、printk()和printf()的最主要区别:

printk()可以指定一个日志级别,内核根据这个级别来判断是否在终端上打印消息。

内核同这个指定的记录等级和当前终端的记录等级console_loglevel来决定是不是向终端上打印。

如果你没有特别指定一个记录等级,函数会选用默认的DEFAULT_MESSAGE_LOGLEVEL。

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

例:

当编译预处理完成后,代码被编译成如下格式:

4、给调用的printk()赋记录等级的方法

(1)保持终端的默认记录等级不变,给所有调试信息KERN_CRIT或更低的等级。

(2)给所有调试信息KERN_DEBUG等级,而调整终端的默认记录等级。

5、内核消息都被保存在一个LOG_BUF_LEN大小的环形队列中。

该缓冲区大小可以在编译时通过设置CONFIG_LOG_BUF_SHIFT进行调整,在单处理器的系统上其默认值是16KB。

**使用环形队列的优劣**

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

四、OOPS

1、oops是内核告知用户有不幸发生的最常用的方式。

这个过程包括向终端上输出错误消息,输出寄存器中保存的信息并输出可供跟踪的回溯线索。

2、如果oops在中断上下文时发生,内核根本无法继续,它会陷入混乱,导致系统死机。

如果oops在idle进程(pid为0)或者init进程(pid为1)时发生,结果同样是系统陷入混乱。

3、oops中包含的重要信息:寄存器上下文和回溯线索。

回溯线索中的地址需要转化成有意义的符号名称:调用ksymoops命令,并且提供编译内核时产生的System.map;如果使用的是模块,还需要一些模块信息。

ksymoops saved_oops.txt

4、kallsyms特性,它可以通过定义CONFIG_KALLSYMS配置选项启用。

五、内核调试配置选项

原子操作:指那些能够不分隔执行的东西,在执行时不能中断否则就是完不成的代码。

六、引发bug并打印信息

1、一些内核调用可以用来方便标记bug,提供断言并输出信息。最常用的两个是BUG()和BUG_ON()。

当被调用的时候,会引发oops。可以把这些调用当做断言使用,想要断言某种情况不该发生:

BUG_ON()比BUG()更清晰、更可读,而且BUG_ON()会将其声明作为一个语句放入unlikely()中。

BUILD_BUG_ON()与BUG_ON()作用相同,仅在编译时调用。

可以用panic()引发更严重的错误:打印错误信息,挂起整个系统,但应该在最糟糕的情况下使用它。

七、神奇的系统请求键

1、神奇的系统请求键(Magic SysRq key),该功能可以通过定义CONFIG_MAGIC_SYSRQ配置选项来启用。当该功能被启用的时候,无论内核处于什么状态,都可以通过特殊的组合键跟内核进行通信。

2、除了配置选项外,还要通过一个sysctl用来标记该特性的开或关:

echo 1 > /proc/sys/kernel/sysrq

八、内核调试器的传奇

1、gdb

可以使用标准的GNU调试器对正在运行的内核进行查看:gdb vmlinux /proc/kcore

其中vmlinux文件时未经压缩的内核映像,它存放在源代码树的根目录上。

/proc/kcore作为一个参数选项,是作为core文件来用的,通过它能够访问到内核驻留的高端内存。

如果编译内核的时候使用-g参数,gdb还可以提供更多的信息。

2、kgdb

是一个补丁,它可以让我们在远端主机上通过串口利用gdb的所有功能对内核进行调试。

九、探测系统

1、用UID作为选择条件

2、使用条件变量

如果代码与进程无关,或者希望有一个针对所有情况都能使用的机制来控制某个特性,可以使用条件变量。

3、使用统计量

需要掌握某个特定事件的发生规律或需要比较多个事件并从中得出规律。

4、重复频率限制:某种事件发生的非常频繁,而又需要观察它的整体进展情况。

发生次数限制:确认在特定情况下某段代码确实被执行了。

不管哪种情况,用到的变量都应该是静态的static,并且应该限制在函数的局部范围以内,这样才能保证变量的值在经历多次函数调用后仍然能够保留下来。

十、用二分查找法找出引发罪恶的变更

一开始,需要一个可靠的可复制的错误,最好是系统一启动就能查证的bug。

接下来,需要一个能确保没问题的内核。

接下来,还需要一个肯定有问题的内核。

十一、使用Git进行二分搜索

一开始,告诉Git进行二分搜索:git bisect start。

如果这个版本一切正常,可以运行下面的命令:git bisect good。

如果证明这个给定的内核版本有bug,可以运行:git bisect bad。

如果你已经知道引发bug的源(比如,x86机型的启动代码),你可以指定git仅仅在与错误相关的目录列表中去二分搜索提交的补丁:git bisect start - arch/x86

总结:

这一章主要介绍了系统调用的知识,与MOOC中的视频教学相辅相成,在许多细节上作了补充,尤其在如何增加一个新的系统调用上介绍的很详细。另外,编写规范的、最优化的、安全的系统调用所遵循的概念和内核接口规范也值得我们注意。

系统调用是利用了软中断的机制,由API、POSIX和C库协调工作。虽然系统调用使用起来非常方便,但仍要尽量避免每出现一种新的抽象就简单的加入一个新的系统调用,而新系统调用增添频率很低也反映出Linux是一个相对较为稳定并且功能已经较为完善的操作系统。

《Linux内核设计与实现》学习总结 Chap18的更多相关文章

  1. Linux内核设计第一周学习总结 计算机如何工作

    北京电子科技学院 20135310陈巧然 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-100002 ...

  2. Linux内核设计第二周学习总结 完成一个简单的时间片轮转多道程序内核代码

    陈巧然 原创作品 转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.使用实验楼的虚拟机 ...

  3. Linux内核设计第四周学习总结 使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用

    陈巧然原创作品 转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 实验目的: 使用库函数A ...

  4. linux内核设计与实现学习笔记-模块

    模块 1.概念:  如果让LINUX Kernel单独运行在一个保护区域,那么LINUX Kernel就成为了“单内核”.    LINUX Kernel是组件模式的,所谓组件模式是指:LINUX K ...

  5. 《Linux内核设计与实现》课本第五章学习笔记——20135203齐岳

    <Linux内核设计与实现>课本第五章学习笔记 By20135203齐岳 与内核通信 用户空间进程和硬件设备之间通过系统调用来交互,其主要作用有三个. 为用户空间提供了硬件的抽象接口. 保 ...

  6. 《Linux内核设计与实现》课本第一章&第二章学习笔记

    <Linux内核设计与实现>课本学习笔记 By20135203齐岳 一.Linux内核简介 Unix内核的特点 Unix很简洁,所提供的系统调用都有很明确的设计目的. Unix中一切皆文件 ...

  7. 《Linux内核设计与实现》 第一二章学习笔记

    <Linux内核设计与实现> 第一二章学习笔记 第一章 Linux内核简介 1.1 Unix的历史 Unix的特点 Unix很简洁,所提供的系统调用都有很明确的设计目的. Unix中一切皆 ...

  8. 《Linux内核设计与实现》第四章学习笔记

    <Linux内核设计与实现>第四章学习笔记           ——进程调度 姓名:王玮怡  学号:20135116 一.多任务 1.多任务操作系统的含义 多任务操作系统就是能同时并发地交 ...

  9. 《Linux内核设计与实现》第五章学习笔记

    <Linux内核设计与实现>第五章学习笔记 姓名:王玮怡  学号:20135116 一.与内核通信     在Linux中,系统调用是用户空间访问内核的唯一手段:除异常和陷入外,它们是内核 ...

  10. 《Linux内核设计与实现》第四章学习笔记——进程调度

                                                                        <Linux内核设计与实现>第四章学习笔记——进程调 ...

随机推荐

  1. python破解网吧收费系统,远控网吧电脑设备!

      我今天呢 , 我就没事跟着朋友喝酒喝酒啊.喝了很多啊.晚上到旁边的酒店开了一个房间,到了酒店才十点! 感觉没啥事情干的,那就去网吧走走看把,看到是一个嘟嘟牛的,和上次是一样的.还是照常用MS170 ...

  2. windows下在idea用maven导入spark2.3.1源码并编译并运行示例

    一.前提 1.配置好maven:intellij idea maven配置及maven项目创建 2.下载好spark源码: 二.导入源码: 1.将下载的源码包spark-2.3.1.tgz解压(E:\ ...

  3. MFC -- Excel操作简介(基于VS2010)

    一.添加与 Excel 操作相关的头文件 项目 -> 类向导,在右上方有一个下拉栏,选择其中的 类型库中的MFC类(T),即可看到下图所示界面,选择“文件”选项,然后在下方的位置选项中添加本地文 ...

  4. [转载]java面试中经常会被问到的一些算法的问题

    Java面试中经常会被问到的一些算法的问题,而大部分算法的理论及思想,我们曾经都能倒背如流,并且也能用开发语言来实现过, 可是很多由于可能在项目开发中应用的比较少,久而久之就很容易被忘记了,在此我分享 ...

  5. JS以及CSS对页面的阻塞

    一.JS阻塞 所有的浏览器在下载JS文件的时候,会阻塞页面上的其他活动,包括其他资源的下载以及页面内容的呈现等等,只有当JS下载.解析.执行完,才会进行后面的 操作.在现代的浏览器中CSS资源和图片i ...

  6. 解决maven update project 后项目jdk变成1.5

    http://blog.csdn.net/jay_1989/article/details/52687934

  7. Java中实现PCA降维

    package com.excellence.splitsentence; import java.net.UnknownHostException; import java.util.ArrayLi ...

  8. week3b:个人博客作业

    vs2013的初步使用 由于自己在写这篇博客的时候已经把vs2013安装完毕,就我写了. 这是2013的使用步骤 第一步 注释 箭头指的方向是“点击” 第二步 第三步 第四步 第5步 第六步 最后点击 ...

  9. synchronized、锁、多线程同步的原理是咋样

    先综述个结论: 一般说的synchronized用来做多线程同步功能,其实synchronized只是提供多线程互斥,而对象的wait()和notify()方法才提供线程的同步功能. 一般说synch ...

  10. iOS- 本地文本容错搜索引擎2-->如何实现英文(英文首字母,汉语拼音)对中文的搜索?

      1.前言 先闲说几句,最近北京的雾霾真是大,呛的我这攻城师都抗不住了.各位攻城师们一定要爱护好自己的身体!空气好时,少坐多动. 如果条件好的话,最好让你们BOSS搞个室内空气净化器.因为那几天一般 ...