ubuntu20.04 搭建kernel调试环境第七篇--gdb调试module

目标:

qemu调试动态加载的内核模块。

步骤:

1,一个终端启动qemu

root@linux:/home/gsf/run-kernel/linux-4.14.186# qemu-system-x86_64 -kernel arch/x86_64/boot/bzImage -drive file=rootfs.f2fs,if=ide,format=raw,id=myid0 --nographic -append "root=/dev/sda console=ttyS0" -hdb ext4.img -net nic,macaddr=52:54:00:12:34:56,model=e1000 -net bridge,id=net0,helper=/usr/lib/qemu/qemu-bridge-helper,br=virbr0 -S -s

qemu启动kernel image,参考之前文章介绍。

网络参数-net nic,macaddr=52:54:00:12:34:56,model=e1000 -net bridge,id=net0,helper=/usr/lib/qemu/qemu-bridge-helper,br=virbr0 参考ubuntu20.04 搭建kernel调试环境第六篇(上)--网络配置。我需要通过http下载待调试的module到qemu中,所以加了这行参数。

2,另一个终端启动gdb

root@linux:/home/gsf/run-kernel/linux-4.14.186# gdb

GNU gdb (Ubuntu 9.2-0ubuntu1~20.04) 9.2

Copyright (C) 2020 Free Software Foundation, Inc.

……

For help, type "help".

Type "apropos word" to search for commands related to "word".

(gdb) file vmlinux

Reading symbols from vmlinux...

(gdb) target remote:1234

Remote debugging using :1234

0x000000000000fff0 in cpu_hw_events ()

(gdb) c

Continuing.

3,下载kernel module到qemu中

本文通过http方法下载(参考ubuntu与qemu共享文件)。在qemu终端中执行:

# wget http://192.168.2.122/kernel.ko

Connecting to 192.168.2.122 (192.168.2.122:80)

saving to 'khttp.ko'

khttp.ko             100% |********************************| 1120k  0:00:00 ETA

'khttp.ko' saved

#

3,加载module的符号表

在ubuntu gdb终端中执行:

0x000000000000fff0 in cpu_hw_events ()

(gdb) c

Continuing.

^C   这里是按键盘Ctrl+C

Program received signal SIGINT, Interrupt.

default_idle () at arch/x86/kernel/process.c:559

559 trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, smp_processor_id());

(gdb) b do_init_module

(gdb) c

Continuing.

在qemu终端中insmod:

# insmod khttp.ko

这个时候,由于ubuntu gdb中触发了断点,该终端不再响应任何输入

在ubuntu gdb中查看.text段、.bss段地址:

Breakpoint 1, do_init_module (mod=0xffffffffa0003000) at ./include/linux/slab.h:488

488 return kmem_cache_alloc_trace(kmalloc_caches[index],

(gdb) print mod->sect_attrs->attrs[1]->name

$1 = 0xffff888006788130 ".text"

(gdb) print mod->sect_attrs->attrs[11]->name

$2 = 0xffff888006788140 ".bss"

(gdb) print /x mod->sect_attrs->attrs[1]->address

$3 = 0xffffffffa0000000

(gdb) print /x mod->sect_attrs->attrs[11]->address

$4 = 0xffffffffa0003340

(gdb)

注意:

1)如果attrs[ ]->name不是.text、.bss,就试试其他的index对应的name,一定要找到.text,.bss在attr数组中的位置。

2)attrs[ ]->address地址值才是我们要用的,不要用成了attrs[ ]->name地址值。

(gdb) add-symbol-file fs/http_kernel_new/khttp.ko 0xffffffffa0000000 -s .bss 0xffffffffa0003340

add symbol table from file "fs/http_kernel_new/khttp.ko" at

.text_addr = 0xffffffffa0000000

.bss_addr = 0xffffffffa0003340

(y or n) y

Reading symbols from fs/http_kernel_new/khttp.ko...

(gdb)

命令格式:add-symbol-file   ko文件   .text段地址  -s .bss  bss段地址

4,设置module中的某个函数为断点,开始调试

(gdb) b download_one_url

Breakpoint 2 at 0xffffffffa0000590: file fs/http_kernel_new/khttp_download.c, line 298.

(gdb) c

Continuing.

当触发了断点时,代码停止执行

Breakpoint 2, download_one_url (url=0xffffffffa00022de "http://10.5.41.228/328M.jpg") at fs/http_kernel_new/khttp_download.c:298

298 {

(gdb)

如果断点设置在module中的某个函数,执行代码断点没生效,解决方法:

1)kernel编译关闭:Randomize the address of the kernel image (KASLR)

2)kernel编译打开:

  [*]    Compile the kernel with debug info

  [*]    Provide GDB scripts for kernel debugging

3)断点函数是inline类型,需去掉inline属性

4)断点函数被优化,需加 __attribute__((optimize("O0")));声明不要优化,如:

int upload_to_server(char *server_dir, char *local_file) __attribute__((optimize("O0")));

posted @ 2021-12-12 14:41  geshifei  阅读(42)  评论(0编辑  收藏  举报  来源