原文地址:
内核调试技术
调试是无法逃避的任务。进行调试有很多种方法,比如将消息打印到屏幕上、使用调试器,或只是考虑程序执行的情况并仔细地分析问题所在。
在修正问题之前,必须先找出问题的源头。举例来说,对于段错误,需要了解段错误发生在代码的哪一行。一旦发现了代码中出错的行,请确定该方法中变量的值、方法被调用的方式以及关于错误如何发生的详细情况。使用调试器将使找出所有这些信息变得很简单。如果没有调试器可用,还可以使用其他的工具。(请注意:有些Linux软件产品中可能并不提供调试器)。
9.1.3 调试方法介绍
内核调试方法很多,主要有以下4类。
n 通过打印函数。 n 获取内核信息。 n 处理出错信息。 n 内核源码调试。
在调试内核之前,通常需要配置内核的调试选项。图9.1给出了“Kernel hacking”配菜单下的各种调试选项。不同的调试方法,需要配置对应的选项。
每一种调试选项针对不同的调试功能。并且不是所有的调试选项在所有的平台上都能够支持。这里介绍一些“Kernel hacking”的调试选项,具体配置使用可以根据情况选择。
图9.1 内核调试选项
(1)编译选项“omit-frame-pointer”。 CONFIG_FRAME_POINTER在“Kernel hacking”中缺省的定义为“Y”。在Makefile根据这个选项来选择GCC编译选项。看看顶层Makefile中的这段代码就明白了。
ifdef CONFIG_FRAME_POINTER CFLAGS +=
-fno-omit-frame-pointer
$(call
cc-option,-fno-optimize-sibling-calls,)
else CFLAGS += -fomit-frame-pointer endif
(2)“Show timing information on printks”。
CONFIG_PRINTK_TIME在printk打印的信息中包含时间信息,可以用来测量内核操作之间的时间间隔。
(3)“Kernel debugging”。
CONFIG_DEBUG_KERNEL选择调试内核选项以后,才可以显示有关的内核调试子项。大部分内核调试选项都依赖于它。
(4)“Magic SysRq key”。
CONFIG_MAGIC_SYSRQ使能系统请求键,可以用于系统调试。 (5)“Kernel log buffer size (16 => 64KB, 17 => 128KB)”。 CONFIG_LOG_BUF_SHIFT设置内核日志缓冲区(log_buf)大小,16表示64KB,17表示128KB。
(6)“Detect Soft Lockups”。
CONFIG_DETECT_SOFTLOCKUP探测内核软死锁状态,例如:有些BUG导致内核一直循环超过10s,而无法调度其他任务执行。一旦探测到死锁状态,内核将打印出当前的堆栈回溯信息。
(7)“Collect scheduler statistics”。
CONFIG_SCHEDSTATS可以在调度器相关的子程序中插入一些代码,采集统计调度器的动作。通过/proc/schedstat接口可以读取这些信息。
(8)“Debug memory allocations”。
CONFIG_DEBUG_SLAB让内核对内存分配进行有限的验证,这会控制管理空闲的内存,会使kmalloc()等函数速度变慢。
(9)“Debug preemptible kernel”。
CONFIG_DEBUG_PREEMPT使能内核抢占调试功能。如果在非抢占安全的状况下使用,将打印警告信息。另外,还可以探测抢占技术下溢。
(10)“Spinlock debugging”。
CONFIG_DEBUG_SPINLOCK使能自旋锁(spinlock)调试功能。捕捉自旋锁初始化等方面的错误,结合NMI watchdog可以调试死锁。
(11)“Sleep-inside-spinlock checking”。
CONFIG_DEBUG_SPINLOCK_SLEEP检查程序中自旋锁内休眠的情况。因为持有自旋锁休眠将可能引起其他任务等待锁。
(12)“kobject debugging”。
CONFIG_DEBUG_KOBJECT可以把更多kobject的调试信息发送到系统日志中。
(13)“Highmem debugging”。
CONFIG_DEBUG_HIGHMEM对高端内存系统进行额外的检查。
(14)“Verbose BUG() reporting (adds 70K)”。
CONFIG_DEBUG_BUGVERBOSE使BUG()的panic报告执行的文件名和调用BUG()的行号。
(15)“Compile the kernel with debug info”。
CONFIG_DEBUG_INFO使内核映像包含调试信息,可以方便内核源码调试。
(16)“Enable ioremap() debugging”。
CONFIG_DEBUG_IOREMAP这个选项会使内核区分ioremap映射的内存和物理内存,并且打印一些回溯信息。
(17)“Debug Filesystem”。
CONFIG_DEBUG_FS支持伪文件系统debugfs,用来存放调试文件。
(18)“Compile the kernel with frame pointers”。
CONFIG_FRAME_POINTER配置内核编译选项:no-omit-frame-pointer。
(19)“Verbose user fault messages”。
CONFIG_DEBUG_USER在应用程序因为例外崩溃的时候,打印错误信息。
(20)“Wait queue debugging”。
CONFIG_DEBUG_WAITQ使能调试等待队列的功能。
(21)“Verbose kernel error messages”。
CONFIG_DEBUG_ERRORS当内核探测到内部错误的时候,打印调试信息。
(22)“Kernel low-level debugging functions”。
CONFIG_DEBUG_LL包含printascii、printch、printhex等调试子程序,方便控制台启动以前的调试工作。
(23)“Kernel low-level debugging via EmbeddedICE DCC channel”。
CONFIG_DEBUG_ICEDCC把调试信息重定向到EmbeddedICE的DCC通道。这仅对于ARM9类型的ICE仿真器可以使用。
(24)“Kernel low-level debugging messages via footbridge serial port”。
CONFIG_DEBUG_DC21285_PORT把调试信息重定向到DC21285(Footbridge)串口。这仅对于特定的硬件平台可用。
(25)“Kernel low-level debugging messages via S3C2410 UART”。
CONFIG_DEBUG_S3C2410_PORT把调试信息重定向到S3C2410串口。这仅对于S3C2410平台可用。
阅读(10235) | 评论(0) | 转发(1) |