Linux内核调试之如何用kdb调试

根据上篇我们讲了搭建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 多平台发布

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值