gdb 和 addr2line 调试内核模块
#include #include MODULE_LICENSE("Dual BSD/GPL"); MODULE_DESCRIPTION ("Oops"); MODULE_AUTHOR("weiqifa"); static int my_oops_init(void) { int *a; a = (int *)0x00003333; *a = 3; printk(KERN_ALERT "oops %d\n",a); return 0; } static void my_oops_exit(void) { printk(KERN_ALERT "Goodbye, oops\n"); } module_init(my_oops_init); module_exit(my_oops_exit) |
ifneq ($(KERNELRELEASE),) EXTRA_CFLAGS = -Wall -g obj-m := oops.o else PWD := $(shell pwd) KVER := $(shell uname -r) KDIR := /lib/modules/$(KVER)/build all: $(MAKE) -C $(KDIR) M=$(PWD) modules clean: rm -rf .*.cmd *.o *.mod.c *.ko .tmp_versions endif |
root@ubuntu:~/linuxBook/oopsmodules# dmesg |tail -20 [ 815.844634] RSP: 0018:ffff88003b933de8 EFLAGS: 00010246 [ 815.844635] RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000001 [ 815.844637] RDX: 0000000000040770 RSI: 0000000000003333 RDI: ffffffffa0359024 [ 815.844638] RBP: ffff88003b933e68 R08: 00000000000030d4 R09: 0000000000000100 [ 815.844639] R10: 8000000000000000 R11: 0000000000000000 R12: ffffffffa0358000 [ 815.844640] R13: 0000000000000000 R14: 0000000001005010 R15: 0000000000000000 [ 815.844641] FS: 00007fb80a1f6700(0000) GS:ffff88003d600000(0000) knlGS:0000000000000000 [ 815.844643] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b [ 815.844643] CR2: 0000000000003333 CR3: 0000000036198000 CR4: 00000000000407f0 [ 815.844687] Stack: [ 815.844689] ffff88003b933e68 ffffffff8100215a 0000000001005010 0000000000000000 [ 815.844691] ffff88003b933e38 ffffffff8105ec93 0000000000000000 0000000000000000 [ 815.844693] 0000000001005010 ffffffffa0020000 ffff88003b933e68 00000000181edb8b [ 815.844695] Call Trace: [ 815.844734] [ [ 815.844740] [ [ 815.844752] [ [ 815.844759] [ [ 815.844761] [ [ 815.844763] [ [ 815.844798] [ [ 815.844800] Code: [ 815.844809] RIP [<ffffffffa0358014>] my_oops_init+0x14/0x30 [oops] [ 815.844812] RSP [ 815.844813] CR2: 0000000000003333 [ 815.844818] ---[ end trace f8f9b64af5078acc ]--- |
[ 815.844809] RIP [<ffffffffa0358014>] my_oops_init+0x14/0x30 [oops] [ 815.844812] RSP |
查看模块的加载地址
root@ubuntu:~/linuxBook/oopsmodules# cat /proc/modules |grep oops oops 13418 1 - Loading 0xffffffffa0358000 (OX+) root@ubuntu:~/linuxBook/oopsmodules# |
使用 addr2line 找到 oops 位置
root@ubuntu:~/linuxBook/oopsmodules# addr2line -e oops.o 0x14 /home/linux/linuxBook/oopsmodules/oops.c:12 root@ubuntu:~/linuxBook/oopsmodules# |
root@ubuntu:~/linuxBook/oopsmodules# objdump -dS --adjust-vma=0xffffffffa0358000 oops.ko oops.ko: file format elf64-x86-64 Disassembly of section .text: ffffffffa0358000 MODULE_LICENSE("Dual BSD/GPL"); MODULE_DESCRIPTION ("Oops"); MODULE_AUTHOR("weiqifa"); static int my_oops_init(void) { ffffffffa0358000: e8 00 00 00 00 callq ffffffffa0358005 ffffffffa0358005: 55 push %rbp int *a; a = (int *)0x00003333; *a = 3; printk(KERN_ALERT "oops %d\n",a); ffffffffa0358006: be 33 33 00 00 mov $0x3333,%esi ffffffffa035800b: 48 c7 c7 00 00 00 00 mov $0x0,%rdi ffffffffa0358012: 31 c0 xor %eax,%eax static int my_oops_init(void) { int *a; a = (int *)0x00003333; *a = 3; ffffffffa0358014: c7 04 25 33 33 00 00 movl $0x3,0x3333 ffffffffa035801b: 03 00 00 00 MODULE_LICENSE("Dual BSD/GPL"); MODULE_DESCRIPTION ("Oops"); MODULE_AUTHOR("weiqifa"); static int my_oops_init(void) { ffffffffa035801f: 48 89 e5 mov %rsp,%rbp int *a; a = (int *)0x00003333; *a = 3; printk(KERN_ALERT "oops %d\n",a); ffffffffa0358022: e8 00 00 00 00 callq ffffffffa0358027 return 0; } ffffffffa0358027: 31 c0 xor %eax,%eax ffffffffa0358029: 5d pop %rbp ffffffffa035802a: c3 retq ffffffffa035802b: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1) ffffffffa0358030 static void my_oops_exit(void) { ffffffffa0358030: e8 00 00 00 00 callq ffffffffa0358035 ffffffffa0358035: 55 push %rbp printk(KERN_ALERT "Goodbye, oops\n"); ffffffffa0358036: 48 c7 c7 00 00 00 00 mov $0x0,%rdi ffffffffa035803d: 31 c0 xor %eax,%eax *a = 3; printk(KERN_ALERT "oops %d\n",a); return 0; } static void my_oops_exit(void) { ffffffffa035803f: 48 89 e5 mov %rsp,%rbp printk(KERN_ALERT "Goodbye, oops\n"); ffffffffa0358042: e8 00 00 00 00 callq ffffffffa0358047 } ffffffffa0358047: 5d pop %rbp ffffffffa0358048: c3 retq ffffffffa0358049: 00 00 add %al,(%rax) ... root@ubuntu:~/linuxBook/oopsmodules# |
*a = 3; ffffffffa0358014: c7 04 25 33 33 00 00 movl $0x3,0x3333 |
使用函数dump_stack()调试内核
#include #include MODULE_LICENSE("Dual BSD/GPL"); static int hello_init(void) { dump_stack(); printk(KERN_ALERT "Hello, world\n"); return 0; } static void hello_exit(void) { printk(KERN_ALERT "Goodbye, cruel world\n"); } module_init(hello_init); module_exit(hello_exit); |
[176360.807755] [ [176360.807776] [ [176360.807779] [ [176360.807931] [ [176360.808709] [ [176360.808717] [ [176360.809093] [ [176360.809097] [ [176360.809100] [ [176360.809187] [ [176360.809308] Hello, world |
实现源码位置
几个比较关键的函数调用关系
dump_stack总结
使用vmlinux调试内核
./prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin/aarch64-linux-android-addr2line -f -e kernel/vmlinux weiqifa@dev:~/rk3399_7in1$ ./prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin/aarch64-linux-android-addr2line -f -e kernel/vmlinux ffffff8008459f3c rk_iommu_domain_free /data/weiqifa/rk3399_7in1/kernel/drivers/iommu/rockchip-iommu.c:1005 (discriminator 2) weiqifa@dev:~/rk3399_7in1$ |
linux@ubuntu:/usr/src/linux-headers-3.13.0-117/kernel$ cat /proc/interrupts CPU0 0: 26 IO-APIC-edge timer 1: 12200 IO-APIC-edge i8042 8: 1 IO-APIC-edge rtc0 9: 0 IO-APIC-fasteoi acpi 12: 110704 IO-APIC-edge i8042 14: 0 IO-APIC-edge ata_piix 15: 0 IO-APIC-edge ata_piix 16: 21165 IO-APIC-fasteoi vmwgfx, snd_ens1371 17: 76243 IO-APIC-fasteoi ehci_hcd:usb1, ioc0 18: 657 IO-APIC-fasteoi uhci_hcd:usb2 19: 197583 IO-APIC-fasteoi eth0 40: 0 PCI-MSI-edge PCIe PME, pciehp |