LDD读书笔记_调试技术

先写一个个人比较喜欢的调试技巧.

1. menuconfig中打开CONFIG_DEBUG_KERNEL

2. objdump -d -S(大写) *.o > file 可以得到混合C和汇编的代码

或者 make *.lst 也能得到

3. addr2line -f -e vmlinux address(0xcxxxxxxxx) 能得到address对应的函数名和所在的文件中的行数

4. 根据OOPS信息, 查看R13(SP), R14(LR), R15(PC)寄存器的值, ARM架构

?printk

?内核中的调试支持

?通过监视调试

?调试系统故障

– oops 消息

– 系统挂起

?调试器和相关工具

– 使用 gdb

– kdb 内核调试器

– kgdb 补丁

– 用户模式的linux虚拟机

– Linux 追踪工具包

– 动态探测

1. printk (最基础常用的)

?printk()函数的健壮性

– 任何时候,任何地方都能调用。(中断,进程,持有锁时,多处理器)

– 脆弱之处:终端初始化之前,不能使用。这时,可能的方法是使用early_printk()或直接进行串口操作。

– 如果没有特别指定等级,默认DEFAULT_MESSAGE_LOGLEVEL,默认是KERN_WARNING。修改可以 "echo n > /proc/sys/kernel/printk"

2. 内核中的调试支持

内核开发者已经在内核自身中构建了多个调试特性.

下面列出开发内核一般使用到的配置选项,一般出现在内核配置工具“kernel hacking”菜单.

?CONFIG_DEBUG_KERNEL #这个选项相当于总开关

?CONFIG_DEBUG_SLAB #这个重要的选项打开了内核内存分配函数的检查

?CONFIG_DEBUG_PAGEALLOC #页在释放时被从内核地址空间去除.

?CONFIG_DEBUG_SPINLOCK #内核捕捉对未初始化的自旋锁的操作, 以及各种其他自旋锁的错误

?CONFIG_DEBUG_SPINLOCK_SLEEP #激活对持有自旋锁时进入睡眠的检查.

?CONFIG_INIT_DEBUG #用__init (或者 __initdata) 标志的项在系统初始化或者模块加载后都被丢弃. 可以用来检查初始化完之后对于初始化的内存空间的访问企图.

?CONFIG_DEBUG_INFO #使得内核在建立时包含完整的调试信息. 如果你想使用 gdb 调试内核, 你将需要这些信息. 如果打算使用gdb, 还要激活CONFIG_FRAME_POINTER.

?CONFIG_MAGIC_SYSRQ #激活"魔术 SysRq"键.

?CONFIG_DEBUG_STACKOVERFLOW

?CONFIG_DEBUG_STACK_USAGE #能帮助跟踪内核堆栈溢出.

第一个选项给内核增加了明确的溢出检查; 第 2 个使得内核监测堆栈使用并作一些统计, 这些统计可以用魔术 SysRq 键得到.

?CONFIG_KALLSYMS #使得内核中包含符号信息; 符号选项用在调试上下文中; 没有它, 一个 oops 列表只能以 16 进制格式给你一个内核回溯.

?CONFIG_IKCONFIG

?CONFIG_IKCONFIG_PROC #使得完整的内核配置状态被建立到内核中, 可以通过 /proc 来访问.一般自己开发的内核是不需要的.

?CONFIG_ACPI_DEBUG #打开详细的 ACPI调试信息.

?CONFIG_DEBUG_DRIVER #打开了驱动核心的调试信息, 可用以追踪低层支持代码的问题.

?CONFIG_SCSI_CONSTANTS #建立详细的 SCSI 错误消息的信息.

?CONFIG_INPUT_EVBUG #打开输入事件的详细日志.

?CONFIG_PROFILING #通常用在系统性能调整, 但是在追踪一些内核挂起和相关问题上也有用.

3. 通过监视调试

? Strace命令是一个功能非常强大的工具,可以显示有用户空间所发出的所有系统调用。

– 不仅显示调用, 还以符号形式显示调用的参数和返回值. 当一个系统调用失败, 错误的符号值(例如, ENOMEM)和对应的字串(Out of memory) 都显示.

– strace 有很多命令行选项; 其中最有用的是

? -t 来显示每个调用执行的时间,

? -T 来显示调用中花费的时间,

? -e 来限制被跟踪调用的类型,

? -o 来重定向输出到一个文件. 缺省地, strace 打印调用信息到 stderr.

4. 调试系统故障

?oops消息

大部分 bug 是引用 NULL 指针或者使用其他不正确指针值. 此类 bug 通常的输出是一个 oops 消息.

– 一个 oops 显示了出错时的处理器状态, 包括CPU 寄存器内容和其他看来不可理解的信息.

– 只在你的内核是打开 CONFIG_KALLSYMS 选项而编译时可以看到符号的调用堆栈. 否则, 如果见到一个裸的 16进制列表, 除非以别的方式对其解码.

?系统挂起

– 尽管内核代码的大部分 bug 以 oops 消息结束, 有时候它们可能完全挂起系统. 如果系统挂起, 没有任何消息可以打印出来,系统不响应任何动作,包括Ctrl-Alt-Del

– 对上述情况一个必不可少的工具是“魔术 sysrq 键”, 在大部分体系上都可用. 魔术键 sysrq 是 PC 键盘上alt 和 sysrq 键组合来发出的

– 开启SysRq功能:

? echo 0 > /proc/sys/kernel/sysrq

5. 调试器和相关工具

?使用gdb

–gdb 对于看系统内部是非常有用. 在这个层次上,精通调试器的使用要求掌握gdb 命令, 需要理解目标平台的汇编代码, 以及对应源码和优化的目标代码匹配的能力.

–典型调用:

?gdb /usr/src/linux/vmlinux /proc/kcore

–可以使用gdb命令来获取信息,如

?p global_variable

?print *(address)

–编译内核-g可以提供更多信息,如打印结构体中的成员和跟踪一个指针

?Kdb内核调试器

–为什么内核没有建立更多高级的调试特性在里面.是Linus不相信交互式的调试器. 他担心它们会导致不良的修改, 这些修改给问题打了补丁而不是找到问题的真正原因.

–kdb 内嵌式内核调试器来自 oss.sgi.com 的一个非官方补丁. 要使用kdb, 你必须获得这个补丁应用它, 重编译并安装内核.仅x86可用

–启动kdb:一种是在启动时加入“kdb=on”,另一种方式是在proc文件系统加载后,输入如下命令:

#echo 1”>/proc/sys/kernel/kdb。

然后就可以按“pause”键进入调试环境了。

–kdb提供丰富的命令实现运行控制、内存操纵、寄存器操纵、断点设置、堆栈跟踪等许多功能

?Kgdb补丁

–将运行调试内核的系统和运行调试器的系统隔离开来工作。两个系统使用串口线缆连接。

–可以让完整功能的gdb针对内核运行。需要对gdb进行一些设置和安装。

–支持x86,SuperH,ia64,x96_64,SPAR和32位的PPC架构

–在Documentation/i386/kgdb下有详细描述

?用户模式的linux虚拟机

–UML 使用 Linux 内核来运行, 作为一个Linux 系统上的独立的用户模式的进程

–好处:

?内核错误不会破坏“真正”的系统

?很容易用gdb等调试器对用户模式的linux进行处理

–缺点:

?用户模式的内核无法访问主机系统的硬件,无法调试真正和硬件打交道的驱动程序

–http://user-mode-linux.sf.net/ 有关于 UML 的更多信息

?Linux 追踪工具包

–Linux Trace Toolkit (LTT) 是一个内核补丁以及一套相关工具, 允许追踪内核中的事件.追踪内容包括时间信息, 可以创建一个给定时间段内所发生事情的完整描述.

因此, 它不仅可以用来调试,也可以追踪性能问题.

–LTT文档一起, 可以在http://www.opersys.com/LTT 找到

?动态探测

–Dynamic Probes ( DProbes ) 是由 IBM 发行的(在 GPL 之下)为 IA-32 体系的 Linux 的调试工具. 它允许安放一个“探针”在几乎系统中任何地方, 用户空间和内核空间都可以.

–探针由一些代码组成( 有一个特殊的,面向堆栈的语言写成), 当控制命中给定的点时执行代码. 代码可以报告信息给用户空间,改变寄存器, 或者做其他很多事情.

–探针可以插入在一个运行中的系统的任何地方, 不用内核重建或者重启. DProbes 可以协助 LTT在任意位置插入新的跟踪事件.

– DProbes 工具可以从 IBM 的开放源码网站:http://oss.sof-ware.ibm.com 下载.

时间: 2024-10-11 22:38:39

LDD读书笔记_调试技术的相关文章

LDD读书笔记_内存管理

本部分不仅仅是LDD的介绍部分, 还包括了对linux的内存模型的总结. 一句话总结 伙伴系统是基石, slab基于伙伴系统, kmalloc基于slab. 要点 ?伙伴系统是对连续大内存而言, 得到的内存的单位从1个page到211 page, 解决外部碎片问题. ?Slab分配器是针对小内存而言, 从32B到128KB, 解决的是内部碎片问题, kmalloc是基于slab分配器的. ?如果物理内存加上需要映射的IO空间内存的大小加起来超过896M, 则有必要开启highmen的功能. Ag

LDD读书笔记_时间,延迟和延缓操作

Agenda ?如何获得当前时间 ?如何度量时间差, 如何比较时间 ?如何将操作延迟指定的一段时间 ?如何调度异步函数到指定的时间之后执行 ?如何获得当前时间 ?HZ: 宏定义, 每秒的时间中断次数 ?Jiffies变量: 系统引导时初始化为0, 每发生一次时间中断就加1 –#include <linux/jiffies.h> –unsigned long j, stamp_1, stamp_half, stamp_n; –j = jiffies; /* current value */ –s

jQuery内核详解与实践读书笔记1:原型技术分解2

上一篇已经搭建了一个非常简陋的jQuery框架雏形,如没有阅读搭建过程,请先阅读<jQuery内核详解与实践读书笔记1:原型技术分解1>初始搭建过程.接下来,完成书中介绍的剩下三个步骤: 7. 延续--功能扩展 jQuery框架是通过extend()函数来扩展功能的,extend()函数的功能实现起来也很简单,它只是吧指定对象的方法复制给jQuery对象或jQuery.prototype对象,如下示例代码就为jQuery类和原型定义了一个扩展功能的函数extend(). 1 var $ = j

&lt;读书笔记&gt;软件调试之道 :从大局看调试-理想的调试环境

声明:本文档的内容主要来源于书籍<软件调试修炼之道>作者Paul Butcher,属于读书笔记.欢迎转载! ----------------------------------------------------------------------------------------------------- 自动化测试 1.有效的自动化测试 明确说明测试结果是否通过 不需要安装.测试后也能够撤销对环境所做的任何修改 单击运行所有的测试 全面覆盖,做到足够解决完全覆盖是可能的 2. 自动化测试

&lt;读书笔记&gt;软件调试之道 :从大局看调试-零容忍策略

声明:本文档的内容主要来源于书籍<软件调试修炼之道>作者Paul Butcher,属于读书笔记.欢迎转载! -------------------------------------------------------------------------------------------- 缺陷优先 如何使缺陷修复与软件开发相结合? 如何估计缺陷修复花费的时间? 如何确保项目不会陷入<人月神话>中所描述的无数缺陷修复的焦油坑中呢? 缺陷优先 要采用早起缺陷修复原则,并且基于以下两

&lt;读书笔记&gt;软件调试之道 :问题的核心-修复后的反思

声明:本文档的内容主要来源于书籍<软件调试修炼之道>作者Paul Butcher,属于读书笔记.欢迎转载! -------------------------------------------------------------------------------------------------- 有时尽管修复设计的是一个孤立的代码区,但你还是需要大局观,在修复缺陷之后花时间反思一下! 一旦确定了错误的来源,就可以采取措施避免它再发生!有些情况下,只不过是告诉你未来在在这一方面要更加小心

&lt;读书笔记&gt;软件调试之道 :问题的核心-如何修复缺陷

声明:本文档的内容主要来源于书籍<软件调试修炼之道>作者Paul Butcher,属于读书笔记.欢迎转载! 修复缺陷 对于一个好的修复来说,不仅仅是让软件运行正确,还需要为将来奠定基础.一些列零散的未经仔细考虑的修改,都将是原本的简洁设计逐步消失. 好的修复必须同时实现以下目标: 修复问题 避免引入回归 维持或者提高代码的整体质量 -----------需要参考的规则如下---------- 1.清除障碍 确保一切从头开始,当你不舍得抛弃诊断阶段所做的修改时,利用源码控制系统. 需要对所做的修

&lt;读书笔记&gt;软件调试之道 :问题的核心-诊断

声明:本文档的内容主要来源于书籍<软件调试修炼之道>作者Paul Butcher,属于读书笔记. 不要急于动手! 尽管可以利用各种工具和技术以及软件自身查找缺陷,但是你最重要的财富是你的智慧 一种调试方法 提出假设->设计实验->假设不成立,重新开始 采用不同类型的实验 进行几种不同类型的实验,但是每种实验必须有一个明确的目标.比如软件内部运行状态.软件的输入参数.本身编码逻辑. 实验必须起到验证的作用 实验是一种达到目的手段,而不是目的的本身.可以通过实验用来证明或者推翻假设.

&lt;读书笔记&gt;软件调试之道 :从大局看调试-发现代码存在问题

声明:本文档的内容主要来源于书籍<软件调试修炼之道>作者Paul Butcher,属于读书笔记.欢迎转载! ----------------------------------------------------------------------------------------------- 缺陷可以随时发生,从代码编写完毕到代码发布后的成年累月! 无论你开发什么样的软件,都需要创建一些流程,通过这些流程,可以告诉你软件哪里出了问题,并且应该如何修复! 1.缺陷管理系统 既有简单用途的,