最近做一些Kernel方面的工作,从一头雾水开始,多做些记录吧。

addr2line也可以根据指令地址定位C代码对应的行,但是对于Kernel module却不是很方便,使用gdb就要容易得多。

NOTE:在使用gdb定位C代码之前需要开启-g选项编译内核或者module

例如有这样的Call Trace
Call Trace:
[<8033265c>] dump_stack+0x8/0x30
[<8003abbc>] warn_slowpath_common+0x70/0x98
[<80041f10>] local_bh_enable_ip+0x98/0xec
[] ieee80211_alloc_node+0x29c/0x47c [umac]
[] ieee80211_reset_bss+0x58/0x154 [umac]
[] ieee80211_vap_attach+0x20/0x68 [umac]
[] ath_vap_create+0x430/0x6b0 [umac]
[] wlan_vap_create+0x58/0x210 [umac]
[] osif_ioctl_create_vap+0x268/0x790 [umac]
[] ath_ioctl+0x134/0x94c [umac]
[<8022db50>] dev_ioctl+0x28c/0x88

现在想定位指令:
[<80041f10>] local_bh_enable_ip+0x98/0xec

可以这样做:
$ mips-linux-gdb vmlinux

GNU gdb 6.8
Copyright (coffee) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later http://gnu.org/licenses/gpl.html
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type “show copying”
and “show warranty” for details.
This GDB was configured as “–host=i386-pc-linux-gnu –target=mips-linux- uclibc”…

输入命令
(gdb) list *(local_bh_enable_ip+0x98)

gdb返回结果
0x80041f10 is in local_bh_enable_ip (kernel/softirq.c:216).
211
212 EXPORT_SYMBOL(_local_bh_enable);
213
214 static inline void _local_bh_enable_ip(unsigned long ip)
215 {
216 WARN_ON_ONCE(in_irq() || irqs_disabled());
217 #ifdef CONFIG_TRACE_IRQFLAGS
218 local_irq_disable();
219 #endif
220 /*
(gdb)