内核调试方法

printk

通过proc/sys/kernel/printk查看打印等级

$ cat /proc/sys/kernel/printk
1       4       1       3

四个数字分别对应:

console_loglevel:控制台使用的日志级别;
default_message_loglevel:调用 printk() 未指定日志级别时使用的日志级别;
minimum_console_loglevel:允许设置的控制台日志级别(console_loglevel)最小值;
default_console_loglevel:系统启动时使用的日志级别。

修改等级

# echo 1  4  1  7 > /proc/sys/kernel/printk
# cat /proc/sys/kernel/printk
1       4       1       7

如果修改不了,可以使用dmesg命令修改

pi@link:~$ sudo dmesg -n debug
pi@link:~$ cat /proc/sys/kernel/printk
8       4       1       3

sysrq

需要在内核配置才能启用

CONFIG_MAGIC_SYSRQ=y

然后在shell下使用,比如查看task

echo 1 >/proc/sys/kernel/sysrq 
echo t > /proc/sysrq-trigger

如果看不到打印,看下dmesg里是否有,调整下控制台打印等级

kdb/kgdb

这步是在编译内核之后进行的,因为有些特性需要在内核编译时就指定,比如kgdb。可以使用menuconfig把kernel debugging和KGDB选项打开,建议的配置

# CONFIG_STRICT_KERNEL_RWX is not set
# CONFIG_RANDOMIZE_BASE is not set
CONFIG_FRAME_POINTER=y
CONFIG_KGDB=y
CONFIG_KGDB_SERIAL_CONSOLE=y
CONFIG_KGDB_KDB=y
CONFIG_KDB_KEYBOARD=y
CONFIG_DEBUG_INFO=y
CONFIG_GDB_SCRIPTS=y

使用make scripts_gdb显式编译gdb脚本
1.kdb
使用实例:

#echo g > /proc/sysrq-trigger
[255170.882750] sysrq: HELP : loglevel(0-9) reboot(b) crash(c) terminate-all-tasks(e) memory-full-oom-kill(f) kill-all-tasks(i) thaw-filesystems(j) sak(k) show-backtrace-all-active-cpus(l) show-memory-usage(m) nice-all-RT-tasks(n) poweroff(o) show-registers(p) show-all-timers(q) unraw(r) sync(s) show-task-states(t) unmount(u) show-blocked-tasks(w) 
#echo ttyAMA0  > /sys/module/kgdboc/parameters/kgdboc  
[255630.457371] KGDB: Registered I/O driver kgdboc
#echo g > /proc/sysrq-trigger
[255639.294716] sysrq: DEBUG

Entering kdb (current=0xffff00001dba4e00, pid 10020) on processor 0 due to Keyboard Entry
[0]kdb> btc
btc: cpu status: Currently on cpu 0
Available cpus: 0-1
Stack traceback for pid 10020
0xffff00001dba4e00    10020    10019  1    0   R  0xffff00001dba5700 *sh
CPU: 0 PID: 10020 Comm: sh Tainted: P           O      5.10.0 #8
Hardware name: Netfactory soc928 EVB (DT)
Call trace:
 dump_backtrace+0x0/0x1b0
 show_stack+0x14/0x30
 dump_stack+0xc4/0xfc
...

常用参数

m$ 操作内存系列
go 继续运行
r$  操作寄存器系列
b$ 操作栈系列
env 查看环境变量
set 设置环境变量//比如 set LINES 10000设置行数
cpu 切换cpu
ps 查看的任务
pid 切换到任务
b$ 操作断点系列
ss 单步操作
dump$  dump信息

2.kgdb/gdb
kgdb相对于kdb来说是源码级调试器
输入kgdb,并等待命令。
可以使用串口连接,或者使用socat实现远程gdb连接kgdb,另外还有agent-proxy小工具可用。
之前尝试过这两种工具发现连上都输入不了,后来发现可能是mac上的ch340驱动有问题,直接echo “xxx”>/dev/tty.wchusbserial220,会直接卡住。但是在wsl2上尝试全部成功。
目前远程方案全部尝试失败,先使用本地
1.接入串口线,使用usbipd实现共享到wsl2
2.在host设备上提前设置好kgdboc,并进入kgdb等待连接
3.使用gdb加载vmlinux,连接串口

(gdb) set serial baud 115200
(gdb) target remote /dev/ttyUSB0
Remote debugging using /dev/ttyUSB0
warning: multi-threaded target stopped without sending a thread-id, using first non-exited thread
Remote 'g' packet reply is too long (expected 312 bytes, got 788 bytes): 00206a09c0ffffff0100000000000000000000000000000040236a09c0ffffff102a173b80ffffff102a173b80ffffff0000000000000000d8464d09c0ffffffffefffff000000004c751808c0ffffffd8464d09c0ffffff200720072007200720072007200720077fb9e509c0ffffff000000000000000077b9e589c0ffffff00000000000000000000000000000000ffffffffffffffff670000000000000000c04709c0ffffff00d04509c0ffffff03000000000000000000000000000000000000000000000018fcc308c0ffffff00000000000000000000000000000000c01eee0180ffffff80bce509c0ffffff4c751808c0ffffff80bce509c0ffffffa4741808c0ffffff0500006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

报错,查看stackoverflow,说要重编gdb,后面再弄,猜测可能需要编build,host=x86-64,target=aarch64的gdb

3.kdb/kgdb切换
$3#33 切换回kdb
$D#44+ 继续运行,退出kgdb

4.从gdb运行kdb命令
可以使用monitor help命令查看可以在gdb使用的kdb命令
5.内核启动参数
kgdboc
kgdboc_earlycon kgdb将使用bootconsole知道使用kgdboc
kgdbwait 在启动内核时等待调试器连接
kgdbcon 在gdb连接到内核时在gdb中看到printk()消息。注意,不能在系统控制台同时使用kgdboc和kgdbcon。当在系统运行时通过echo 1 > /sys/module/kgdb/parameters/kgdb_use_con配置了此功能,必须在下次i/o重配置时才能生效
kgdbreboot 更改调试器处理重新启动通知的方式
nokaslr 禁用随机化
6.同时进行调试和打印查看
可参考基于A33下linux内核的GDB+KGDB内核调试环境搭建的agent-proxy方法,或者尝试使用socat,比如linux云服务器之间利用socat进行虚拟串口通信采用一对串口的方式,或者使用socat使用网络转接
7.注意事项

在用 gdb 来调试内核的时候,由于内核在初始化的时候,会创建很多子线程。而默认 gdb
会接管所有的线程,如果你从一个线程切换到另外一个线程, gdb 会马上把原先的线程暂停。但是这样很容易导致 kernel 死掉,所以需要设置一下 gdb 。一般用 gdb 进行多线程调试,需要注意两个参数: follow-fork-mode 和detach-on-fork。

TRACE_EVENT,tracepoint使用

参考

内核通用调试方法
Development tools for the kernel
linux内核调试方法
内核调试跟踪
brendangregg的主页
linux 内核启动Initramfs与initrd 及其挂载
Ramfs, rootfs and initramfs
vscode+kgdb+qemu调试linux内核
使用gdb调试内核
关于Linux内核vmlinuz、initrd.img和System.map
关于内核镜像文件vmlinux-vmlinuz-vmlinux.bin-zimage-bzimage-uImage 之间的差异
RaspberryPi
Linux:内核调试之内核魔术键sysrq
Linux kernel:修改内核 printk 日志等级
Using kgdb, kdb and the kernel debugger internals
linux云服务器之间利用socat进行虚拟串口通信

gdb脚本报错
GNU调试器 GDB 8.3 发布及安装更新,支持RISC-V与IPv6连接等
玩转C++调试之Python的GDB库增强
GDB解coredump文件报Python异常解决办法
内核调试- vmlinux-gdb.py无法在gdb上运行

socat使用
socat网络工具

gdb报错
Remote ‘g’ packet reply is too long
Remote ‘g’ packet reply is too long问题的解决
小工具
agent-proxy小工具——用一个串口,既当控制台又当kgdb调试通道

相关推荐

  1. 内核调试方法

    2024-07-11 05:12:03       22 阅读
  2. 【C语言】内存泄漏调试方式

    2024-07-11 05:12:03       29 阅读
  3. Linux内核调试之如何用kdb调试

    2024-07-11 05:12:03       32 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-11 05:12:03       66 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-11 05:12:03       70 阅读
  3. 在Django里面运行非项目文件

    2024-07-11 05:12:03       57 阅读
  4. Python语言-面向对象

    2024-07-11 05:12:03       68 阅读

热门阅读

  1. 指令v-el的作用是什么

    2024-07-11 05:12:03       24 阅读
  2. html转换到pdf

    2024-07-11 05:12:03       25 阅读
  3. 【Rust】字符串String类型学习

    2024-07-11 05:12:03       24 阅读
  4. Docker修改国内镜像源

    2024-07-11 05:12:03       19 阅读
  5. docker无法拉取镜像,推荐可以使用下面镜像源

    2024-07-11 05:12:03       21 阅读
  6. Spring Boot Vue 毕设系统讲解 7

    2024-07-11 05:12:03       25 阅读
  7. influxdb时序数据库常用命令

    2024-07-11 05:12:03       24 阅读