根据上篇我们讲了搭建ARM64 QEMU环境没看到的小伙伴务必看下上篇,在看本篇内容。
本篇讲讲如何用kdb进行Linux内核调试。
环境准备
PC系统:Windows10
虚拟机:VMware-17
虚拟机系统:Ubuntu-20.04
模拟的64位cpu:cortex-a57
kdb简介
由于使用gdb调试内核时,不能执行打断点、单步调试以及修改变量等操作,而这些操作是实际调试工作的基石。为了更加方便内核调试,社区开发了内核级的调试模块kdb和kgdb,通过它们可以实现对内核的在线调试。而本篇介绍的kdb是Linux内核的一个命令行调试器,可以让我们通过命令行界面对内核进行调试。其中kdb可以在本机独立运行,当需要执行调试工作时,可通过sysrq命令或按键等方式进入调试器。然后就可以在调试器中执行打断点、单步调试、修改寄存器、内存,以及查看变量,调用栈等调试命令。
kdb特性
它的特性主要有:
1、调试支持:KDB支持多进程、多线程调试,可以在多CPU上进行调试,同时支持几种核心调试技术,包括单步、断点、进程状态检查、运行状态检查、记录系统调用、跟踪系统调用等。
2、安全性:KDB通过在操作系统内核运行时采用内存保护机制,保证了内核指令不受外部调试器或恶意软件影响,从而确保了系统的安全性。
3、可移植性:KDB采用标准C语言编写,可以方便的移植到不同的系统上,这使得调试工具可以快速地应用到其它不同的Linux操作系统中。
kdb配置
(1)若要使能kdb,内核需要使能以下配置选项:
CONFIG_DEBUG_INFO=y
CONFIG_FRAME_POINTER=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_MAGIC_SYSRQ_SERIAL=y
CONFIG_KGDB_SERIAL_CONSOLE=y
CONFIG_KGDB_KDB=y
CONFIG_KGDB=y
(2)此外qemu启动内核
qemu-system-aarch64 -machine virt,virtualization=true,gic-version=3 -nographic -m size=1024M -cpu cortex-a57 -smp 4 -kernel arch/arm64/boot/Image -initrd rootfs.cpio.gz -append "root=/dev/ram console=ttyAMA0,115200 rdinit=/linuxrc"
(3)命令行中给kgdboc节点注册I/O驱动
[root@pan ]# echo "ttyAMA0,115200" > /sys/module/kgdboc/parameters/kgdboc
[ 342.747279] KGDB: Registered I/O driver kgdboc
启动kdb
当配置好kdb后, 可通过sysrq命令进入kdb,其命令格式如下:
[root@pan ]# echo g > /proc/sysrq-trigger
[ 1409.114995] sysrq: DEBUG
Entering kdb (current=0xffff24b6d91a8e40, pid 116) on processor 3 due to Keyboard Entry
[3]kdb>
(2)此外,在内核挂死后,系统也会自动进入kdb,从而使用户可以方便地调试问题。例如,下例为通过sysrq命令进入手动panic,此时系统会自动进入kdb:
[root@pan ]# echo c > /proc/sysrq-trigger
[ 1588.968148] sysrq: Trigger a crash
[ 1588.969180] Kernel panic - not syncing: sysrq triggered crash
[ 1588.969919] CPU: 3 PID: 116 Comm: sh Not tainted 5.10.209 #2
[ 1588.970355] Hardware name: linux,dummy-virt (DT)
[ 1588.970677] Call trace:
[ 1588.971055] dump_backtrace+0x0/0x1d0
[ 1588.971416] show_stack+0x18/0x38
[ 1588.971718] dump_stack+0xf0/0x12c
[ 1588.972057] panic+0x1b0/0x3b4
[ 1588.972376] sysrq_handle_crash+0x1c/0x20
[ 1588.972761] __handle_sysrq+0xbc/0x1b0
[ 1588.973130] write_sysrq_trigger+0x94/0xe0
[ 1588.973454] proc_reg_write+0xcc/0x108
[ 1588.973787] vfs_write+0xc0/0x388
[ 1588.974090] ksys_write+0x6c/0x100
[ 1588.974421] __arm64_sys_write+0x1c/0x28
[ 1588.974659] el0_svc_common.constprop.4+0x68/0x188
[ 1588.974843] do_el0_svc+0x24/0xa0
[ 1588.974966] el0_svc+0x14/0x20
[ 1588.975185] el0_sync_handler+0x90/0xb8
[ 1588.975368] el0_sync+0x160/0x180
PANIC: sysrq triggered crash
Entering kdb (current=0xffff24b6d91a8e40, pid 116) on processor 3 due to Keyboard Entry
[3]kdb>
2.3 kdb简单使用
(1)查看帮助信息
[3]kdb> help
Command Usage Description
----------------------------------------------------------
md <vaddr> Display Memory Contents, also mdWcN, e.g. md8c1
mdr <vaddr> <bytes> Display Raw Memory
mdp <paddr> <bytes> Display Physical Memory
mds <vaddr> Display Memory Symbolically
mm <vaddr> <contents> Modify Memory Contents
go [<vaddr>] Continue Execution
rd Display Registers
rm <reg> <contents> Modify Registers
ef <vaddr> Display exception frame
bt [<vaddr>] Stack traceback
btp <pid> Display stack for process <pid>
bta [D|R|S|T|C|Z|E|U|I|M|A]
Backtrace all processes matching state flag
btc Backtrace current process on each cpu
btt <vaddr> Backtrace process given its struct task address
env Show environment variables
set Set environment variables
help Display Help Message
more>
(2)查看内存的值(md),例如:
[3]kdb> md 0xffff0000
(3)修改内存的值(mm),例如
[3]kdb> mm 0xffff0000 0x1234
(4)显示cpu寄存器的内容(rd),例如
[3]kdb> rd
x0: ffffcb590aab7000 x1: ffffcb590aab7918 x2: 0000000000000001
x3: 0000000000000000 x4: ffffcb590aa17a20 x5: ffff24b6c26e6c80
x6: 000000000000000a x7: 000000000000001d x8: 7f7f7f7f7f7f7f7f
x9: 3734ff0967726071 x10: 7f7f7f7f7f7f7f7f x11: 0101010101010101
x12: 0000000000000028 x13: ffffffffffffffff x14: ff00000000000000
x15: ffffffffffffffff x16: 0000000000000000 x17: 0000000000000000
x18: ffffffffffffffff x19: ffffcb590aa8b9e8 x20: ffffcb590aa8b9e8
x21: 0000000000000000 x22: ffffcb590a0920b8 x23: 0000000000000000
x24: 0000000000000007 x25: 0000000000000000 x26: ffffcb590aa11000
x27: 0000000000000000 x28: ffff24b6d91a8e40 x29: ffff800010223c10
x30: ffffcb5908d6a004 sp: ffff800010223c10 pc: ffffcb5908d68d38
(5)修改cpu寄存器的内容(rm)
[3]kdb> rm x3 0x9
[3]kdb> rd
x0: ffffcb590aab7000 x1: ffffcb590aab7918 x2: 0000000000000001
x3: 0000000000000009 x4: ffffcb590aa17a20 x5: ffff24b6c26e6c80
x6: 000000000000000a x7: 000000000000001d x8: 7f7f7f7f7f7f7f7f
x9: 3734ff0967726071 x10: 7f7f7f7f7f7f7f7f x11: 0101010101010101
x12: 0000000000000028 x13: ffffffffffffffff x14: ff00000000000000
x15: ffffffffffffffff x16: 0000000000000000 x17: 0000000000000000
x18: ffffffffffffffff x19: ffffcb590aa8b9e8 x20: ffffcb590aa8b9e8
x21: 0000000000000000 x22: ffffcb590a0920b8 x23: 0000000000000000
x24: 0000000000000007 x25: 0000000000000000 x26: ffffcb590aa11000
x27: 0000000000000000 x28: ffff24b6d91a8e40 x29: ffff800010223c10
x30: ffffcb5908d6a004 sp: ffff800010223c10 pc: ffffcb5908d68d38
pstate: 20000085 v0: ?? v1: ?? v2: ?? v3: ?? v4: ?? v5: ?? v6: ?? v7: ??
v8: ?? v9: ?? v10: ?? v11: ?? v12: ?? v13: ?? v14: ?? v15: ?? v16: ??
v17: ?? v18: ?? v19: ?? v20: ?? v21: ?? v22: ?? v23: ?? v24: ?? v25: ??
v26: ?? v27: ?? v28: ?? v29: ?? v30: ?? v31: ?? fpsr: 00000000
fpcr: 00000000
(6)打印cpu的栈指针
[3]kdb> bt
Stack traceback for pid 116
0xffff24b6d91a8e40 116 1 1 3 R 0xffff24b6d91a9840 *sh
CPU: 3 PID: 116 Comm: sh Not tainted 5.10.209 #2
Hardware name: linux,dummy-virt (DT)
Call trace:
dump_backtrace+0x0/0x1d0
show_stack+0x18/0x38
dump_stack+0xf0/0x12c
kdb_dump_stack_on_cpu+0x88/0x90
kdb_show_stack+0x98/0xa8
kdb_bt1+0xc8/0x130
kdb_bt+0x324/0x368
kdb_parse+0x390/0x738
kdb_main_loop+0x578/0x998
kdb_stub+0x250/0x458
kgdb_cpu_enter+0x334/0x748
kgdb_handle_exception+0x114/0x120
kgdb_compiled_brk_fn+0x2c/0x40
call_break_hook+0x68/0x80
brk_handler+0x1c/0x60
do_debug_exception+0xa0/0x120
el1_dbg+0x38/0x58
(7)设置断点(bp),例如:
[3]kdb> bp vaddr
(8)单步调试(ss),例如
[3]kdb> ss
(9)退出kdb(go),例如
[3]kdb> go
[root@pan ]#
以上就是我给大家介绍如何用kdb调试内核。
参考:https://zhuanlan.zhihu.com/p/546416941 Linux KDB:轻松解决Linux内核调试问题(linuxkdb)-数据运维技术 (dbs724.com)
作者潘小帅, 是一名Linux底层爱好者,平时写写技术原创文章,徒步,旅游,看电影的爱好,喜欢我的文章可以点赞收藏+关注,感谢你的支持,微信公众号【Linux随笔录】
本文由 mdnice 多平台发布