二分查找方法和printk打印级别
人生就是一个茶几,上面摆满了杯具。内核也是一个大茶几,不过它上面的杯具是一个个的bug。确定bug什么时候被引入是一个很关键的步骤,在这个定位bug的过程中,不论有意或无意,都会很自然地用到二分查找的方法。
二分查找法的基本原理
对于二分查找法,我们不会也不应该会感到陌生。作为一种高效的查找算法,它曾出现在我们的数据结构课堂里,出现在一次又一次的面试里,更是会频繁地应用在我们的代码里。在我们所接触到的各种算法里,它可以说是最为大众化、最充满生活智慧的一个,很多人并不知道二分查找法的概念,却能够在生活中熟练的去应用。
比如,一个工人要维修一条10km长的电话线,首先他需要定位出故障所在,如果沿着线路一小段一小段地查找,显然非常得困难,每查一个点都要爬一次电线杆,10km长的距离会有大约200多根电线杆。假设电线两端分别为A、B,这时他会很自然地首先从中间的C开始查起,用话机向两端测试时,发现AC段正常,故而断定故障在BC段,再到BC段的中点D,如果发现BD段正常,则故障在CD段,然后再到CD的中间点E查找,这样每查一次,就可以把待查线路的长度缩减一半,因而经过7次查找,就可以将故障发生的范围缩小到50~100m左右,即在一两根电线杆附近。如此一来要节省很多的精力与时间。
这是二分查找法在生活中的一个典型应用,实际上,查找内核的bug与查找电话线的故障相比,本质上都是相同的,并没有高深到哪里去,都是首先要定位出故障的位置,然后去解决它。
比如你在使用某个版本的内核时,发现了一个内核bug,这时你需要知道它究竟是在应用哪个补丁时被引入的,如果一个一个的去还原那些补丁,每还原一个补丁就要测试一次内核,那么必然会浪费过多的时间,而应用二分查找法,首先确定一个肯定没有出现该bug的内核版本,然后去测试位于这两个版本中间的那个版本,这样重复筛选,就能够很容易的定位出是从哪个版本开始出现了这个bug。
printk()
printk()应该是每一个驱动开发者最为亲密的伙伴了,我们常常将它与二分查找法结合在一起寻找代码中发生问题的位置。
通常情况下,对于代码中的两个printk()语句,如果一个正常执行,而另一个没有被执行,就说明问题发生在这两个printk()之间,接下来就可以在这个范围内应用二分查找法定位有问题的代码。
1. printk()与printf()
用户空间有printf(),内核空间有printk(),它们就如代表善与恶的命运双生子,即使长相功能如何的接近,都不能在代码中共存。
对于我们来说,最容易犯的错误是,在需要printk()的地方误用了printf(),而在需要printf()的地方却又误用了printk(),通常这都不会是因为不知道它们的区别,而只是习惯使然。民间流传有这样的说法:当你在编写用户空间应用程序的时候,下意识写出的都是printk(),那么就说明你是个标准的内核开发者了。
2. printk()的消息级别
printk()与printf()的一个重要区别就是前者可以指定消息的打印级别,内核根据这个指定的级别来决定是否将消息打印到终端上。如下表所示,printk()共有8个级别。
级别 | 描述 |
KERN_EMERG | 紧急情况,系统可能会崩溃 |
KERN_ALERT | 必须立即响应 |
KERN_CRIT | 临界情况 |
KERN_ERR | 错误信息 |
KERN_WARNING | 警告信息 |
KERN_NOTICE | 普通的但可能需要注意的信息 |
KERN_INFO | 提示性信息 |
KERN_DEBUG | 调试信息 |
如果没有指定消息的级别,printk()会使用默认的DEFAULT_MESSAGE_LOGLEVEL(通常是KERN_WARNING)。
3. 控制台的日志级别(console_loglevel)
当printk指定的消息级别小于指定的控制台日志级别时,消息的内容就会显示在该控制台上。控制台的日志级别定义在include/linux/kernel.h文件中,默认为DEFAULT_CONSOLE_LOGLEVEL(值等于7),也就是说默认情况下,比KERN_DEBUG级别高的printk()消息内容都可以在控制台上显示。
我们可以执行下面的命令使任何级别的printk()消息都被打印在终端上
$ echo 8 > /proc/sys/kernel/printk
4. printk()的变体
内核在include/linux/kernel.h文件中提供了两个printk()的变体pr_debug和pr_info,它们的定义为:
235 #define pr_debug(fmt,arg...) /
236 printk(KERN_DEBUG fmt,##arg)
244 #define pr_info(fmt,arg...) /
245 printk(KERN_INFO fmt,##arg)
5. printk()不是万能的
printk()虽然很好用,但它并不是万能的,在系统启动时,终端还没有初始化之前,它并不能被使用,不过如果不是在调试系统的启动过程的话,这并不能算是个问题。
其实内核提供了一个printk()的变体early_printk(),专门用于在系统启动的初期在终端上打印消息,它与printk()的区别仅仅在于名字的不同以及它能够更早地工作。
二分查找方法和printk打印级别的更多相关文章
- 更改printk打印级别
1.查看当前控制台的打印级别 cat /proc/sys/kernel/printk 4 4 1 7 其中第一个"4"表示内核打印函数printk的打印级别,只有 ...
- 更改printk打印级别【转】
本文转载自:http://blog.csdn.net/weed_hz/article/details/8949140 1.查看当前控制台的打印级别 cat /proc/sys/kernel/print ...
- printk打印级别
默认级别 # cat /proc/sys/kernel/printk 4 4 1 7 分别是:控制台日志级别.默认的消息日志级别.最低的控制台日志级别和默认的控制台日志级别 举例 # echo 0 & ...
- 终端下更改printk打印级别
如何去更改printk的打印级别? 1.查看当前控制台的打印级别 # cat /proc/sys/kernel/printk 该文件有4个数字值,它们根据日志记录消息的重要性,定义将其发送到何处,上面 ...
- linux内核打印级别
1.printk()是一个内核的一个记录日志的机制,经常用来记录信息或者警告.printk可以指定输出日志的优先级,在include/linux/kern_levels.h中有相应的宏定义 #defi ...
- java面试记录二:spring加载流程、springmvc请求流程、spring事务失效、synchronized和volatile、JMM和JVM模型、二分查找的实现、垃圾收集器、控制台顺序打印ABC的三种线程实现
注:部分答案引用网络文章 简答题 1.Spring项目启动后的加载流程 (1)使用spring框架的web项目,在tomcat下,是根据web.xml来启动的.web.xml中负责配置启动spring ...
- 实现 sqrt(x):二分查找法和牛顿法
最近忙里偷闲,每天刷一道 LeetCode 的简单题保持手感,发现简单题虽然很容易 AC,但若去了解其所有的解法,也可学习到不少新的知识点,扩展知识的广度. 创作本文的思路来源于:LeetCode P ...
- ASP.NET Core 中文文档 第二章 指南(4.10)检查自动生成的Detail方法和Delete方法
原文 Examining the Details and Delete methods 作者 Rick Anderson 翻译 谢炀(Kiler) 校对 许登洋(Seay).姚阿勇(Mr.Yao) 打 ...
- PHP-----二维数组和二分查找
二维数组由行和列组成.由arr[$i][$j]表示,先后表示行和列,类似于坐标点. 打印二维数组-----通过两次遍历,第一次遍历每一行,第二次遍历每一行的具体元素,并且通过使用count($arr[ ...
随机推荐
- hive的常见判断与抽样函数
.If函数:if和case差不多,都是处理单个列的查询结果 语法: if(boolean testCondition, T valueTrue, T valueFalseOrNull) 返回值: T ...
- 顶尖 API 文档管理工具 (Yapi)
原文地址:https://www.jianshu.com/p/a97d2efb23c5
- C语言实例:类型转换
数组转换成16进制数: #include <stdio.h> #include <stdlib.h> typedef unsigned char UINT8; typedef ...
- Yii2 mysql查询 int自动变string解决办法
原因是PDO以string查询数据导致. 这个与YII没关系,是PDO的默认处理,解决方法只需在配置中的db配置中加上attributes的相关配置就行了,如下: 'components' => ...
- mysql基操
创建数据表: create table tt1( id int, name varchar(20), age int,sex boolean ); insert into tt1 values(1,& ...
- 部署springboot项目时 打包成jar时包中html,js,css文件缺失
问题 打包出来的jar包里面没有html,js,css文件 解决方案 在pom.xml文件下的build选项中的src/main/resources的目录下 添加配置 <build> &l ...
- P4233 射命丸文的笔记
思路 题目要求求的是哈密顿回路的期望数量,实际上就是哈密顿回路的总数/有哈密顿回路的竞赛图的数量 n个点的所有竞赛图中哈密顿回路的总数为 \[ (n-1)! 2^{\frac{n(n-1)}{2}-n ...
- 错误模块“AspNetCoreModuleV2"解决
如图 HTTP 错误 500.21 - Internal Server Error 处理程序"aspNetCore"在其模块列表中有一个错误模块"AspNetCoreMo ...
- 实验一:c++简单程序设计(1)
实验结论 编程练习2-28 switch版源码: #include <iostream> using namespace std; int main(void) { cout <&l ...
- If嵌套
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...