Debugging Techniques [LDD3 04]

本文介绍了Linux内核调试的挑战和内核中的调试支持,如kernel配置中的DEBUG选项,如DEBUG_SLAB、DEBUG_PAGEALLOC等,以及printk的使用,包括loglevel和消息定向。此外,还提到了魔法SysRq键和一些特定设备驱动的调试选项,如CONFIG_SCSI_CONSTANTS和CONFIG_INPUT_EVBUG。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

kernel相较于user,debug起来更加困难,原因有很多,比如kernel中代码的执行是并发的,靠event来驱动;而且kernel一旦出现了bug,很容易把整个系统搞挂,导致后面的现场无法trace,本章就介绍了一些kernel中的debug技巧。

Debugging Support in the Kernel

kernel的发行版都是production code,也就是说里面包含的debug用的信息很少。作为device driver的开发人员,自然得要自己build debug版的kernel才方便debug。

kernel的config包含了很多debug相关的配置,这些配置在“kernel hacking”中都可以找到:

CONFIG_DEBUG_KERNEL

在其他的debug选项打开之前,先要打开这个,虽然它并不能enable什么debug feature。

CONFIG_DEBUG_SLAB

主要针对kernel memory的检查,比如访问未初始化的内存,或者访问已经被释放的内存,以及写越界等。debug选项打开的时候,kernel会在被分配的memory前后加一些guard,以检查对memory的不合理的访问。

CONFIG_DEBUG_PAGEALLOC

减慢page free的速度,以检查可能存在的memory corrupt问题。(?)

CONFIG_DEBUG_SPINLOCK

选项打开的时候,可以检查使用没有初始化 的spinlock,或者lock了两次这种问题。

CONFIG_DEBUG_SPINLOCK_SLEEP

用于检查在持有spinlock的情况下sleep的发生。

CONFIG_INIT_DEBUG

在module init的时候,标记了__init,或者__initdata的函数或者数据,会在init做完以后被释放。打开了这个选项,可以检查在init做完以后仍然对初始化函数或者初始化数据的访问。

CONFIG_DEBUG_INFO

如果打开了这个选项,生成的kernel image会包含各种debug的信息,这样就可以使用gdb来debug kernel。当然,如果要使用gdb,还需要打开CONFIG_FRAME_POINTER。

CONFIG_MAGIC_SYSRQ

打开“magic SysRq” 按键,后面会讲。

CONFIG_DEBUG_STACKOVERFLOW

CONFIG_DEBUG_STACK_USAGE

打开这两个选项,可以trace stack overflow的问题。一般情况下,如果发生了stack overflow,往往stack是被破坏的。如果打开了DEBUG_STACKOVERFLOW,kernel会在stack上增加check;如果打开了STACK_USAGE,kernel会统计stack的使用信息。

CONFIG_KALLSYMS

打开这个选项,build出来的kernel image包含kernel的symbol信息。默认是打开的,否则stack打印出来全是十六进制,没有函数名等。这个选项在“General setup/Standard features”下面。

CONFIG_IKCONFIG

CONFIG_IKCONFIG_PROC

这两个选项在“General setup”下面。会把kernel所有的config都打开,并且在/proc下创建节点?

CONFIG_ACPI_DEBUG

在“Power management/ACPI.”下面,如果在检查power相关的bug,可以打开这个选项。所谓的ACPI,意思是Advanced Configuration and Power Interface。

CONFIG_DEBUG_DRIVER

在“Device Driver”下面,如果在driver core中打开这个选项,可以trace low-level里的code。

CONFIG_SCSI_CONSTANTS

在“Device drivers/SCSI device support,”选项下面,打开SCSI的信息打印。

CONFIG_INPUT_EVBUG

在“Device drivers/Input device support”下面,打开之后会打印很多和input device相关的信息。

CONFIG_PROFILING

在“Profiling support.”下面,主要用于分析kernel的performance,也能用于trace system hang或别的error。

下面是介绍debug kernel的一些手段。

Debugging by Printing

 最常用的debug手段仍然是print。在user mode,可以使用printf来打印信息,在kernel中,需要使用printk。

printk

printk和user mode printf有些不同,这些不同体现在很多方面。比如printk可以指定loglevel,或者优先级,在打印时通过一些宏就可以指定loglevel,比如:

KERN_EMERG

用在紧急情况下,通常是发生了crash。

KERN_ALERT

提醒,表示需要立即操作。

KERN_CRIT

critical情况的发生,通常是硬件或者软件操作失败。

KERN_ERR

有错误发生,通常用来指硬件设备产生了错误。
KERN_WARNING

产生警告

KERN_NOTICE

情况一般,但是需要提醒,很多安全相关的log是这个等级。

KERN_INFO

一般的信息打印,很多driver启动或者运行时会通过这个loglevel打印信息。

KERN_DEBUG

用于打印debug信息

上面的8个loglevel,对应了0-7这些整形数,越小的数字log level越高。如果打印时没有指定,就使用DEFAULT_MESSAGE_LOGLEVEL,这个值具体是哪个,需要看当前kernel的配置。

根据当前的loglevel,kernel可以控制打印到什么地方,比如console,terminal,serial port,或者打印机等。如果log等级比console_loglevel低,那么就一行行的打印到console里去。如果klogd和syslogd都在运行,kernel的log会被打印到/var/log/messages里面去。如果klogd没有运行,那么kernel的log不会主动送到user space,除非自己去读/proc/kmsg(可以使用dmesg命令)。kernel的loglevel可以自己修改:

# echo 8 > /proc/sys/kernel/printk

通过向printk写值,可以控制信息打印的等级。

Redirecting Console Messages

这里似乎用不到,不看了。

How Messages Get Logged

To be continued

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值