1 简介 这个文档记录了用 kGDB 调试 Linux 内核的全过程,都是在前人工作基础上的一些总结。以下操作都是基于特定板子来进行,但是大部分都能应用于其他平台。 2 配置内核 2.1 基本配置 在内核配置文件 .config 中,需要打开如下选项: CONFIG_KGDB 加入KGDB支持 CONFIG_KGDB_SERIAL_CONSOLE 使KGDB通过串口与主机通信 2.3 启动参数 打开相应的选项后,需要配置 kernel 启动参数,使 KGDB 和内核能够找到正确的通信接口。 在其他板子上,若使用以太网口来和 KGDB 进行通信,则要把 kgdboc 换成 kgdboe(kgdb over ethernet) )。 配置完后,就可以正常编译,然后把内核下载到目标板上面。 则需要根据这一部分,修改串口驱动程序,若能正常进入 kgdb ,则忽略该节,直接进入下一节使用 KGDB 。
---- 前言 调试内核肯定不是什么轻松的事情, 这里是使用kgdb进行调试, 你理解的没错, 就是kernel版的gdb. ---- 虚拟机串口设置 首先克隆下已经重新编译内核的虚拟机 然后设置两者的串口 update-grub nokaslr, 禁止内核地址随机化, 具体内容请自行google: reboot 然后重启的时候, 就能够看到一行关于nokaslr的提示了. ---- 开始调试 然后开始测试一下kgdb 的调试, 目标机切换为root用户, 控制权限交给kgdb, 目标机进入假死状态: echo g > /proc/sysrq-trigger 开发机进入自编译内核目录 gdb . 目标机切换为root用户, 控制权限交给kgdb, 目标机进入假死状态: echo g > /proc/sysrq-trigger 开发机进入自编译内核目录 gdb .
本文旨在介绍下几种常见的调试方法gdb、crash、kgdb and kdb 以及dynamic debug. 2.3 kgdb KGDB 适合深入的远程内核调试,而 KDB 更适合快速本地访问和简单问题的诊断。两者的使用依赖于具体的调试需求和环境设置。 kgdb的使用步骤如下: 2.3.1 准备内核 Kernel hacking ---> <*> KGDB: kernel debugger ---> [*] KGDB: use kgdb over the serial console [ ] KGDB: internal test suite [ ] KGDB_KDB: include kdb frontend for kgdb [ ] KGDB over Ethernet 2.3.2 添加启动参数 kgdboc=ttyS0,115200 kgdbwait 2.3.3 调试机(host)上启动gdb作为前端
利用KGDB双机调试内核 1.1. 环境 1.2. 配置内核编译环境 2. 参考 双机调试Linux内核环境配置。 利用KGDB双机调试内核 环境 centos 7 VMware 全程使用root用户 配置内核编译环境 这种方式调试内核需要两台机器,一台用来运行Linux内核,另一台对内核进行调试。 : kernel debugging with remote gdb [*] KGDB: kernel debugger ---> KGDB: use kgdb over the serial cp System.map /boot/System.map-xxx-kgdb cp initrd.img /boot/initrd.img-xxx-kgdb 客户机修改设置开机启动项的grub配置文件 (我测试ttyS0不行,改成ttyS1可以了) 参考 http://blog.nsfocus.net/gdb-kgdb-debug-application/ 在VMware中用Kgdb调试linux内核
回到正题linux内核调试用的kgdb,一种专门针对linux内核的调试工具,所谓的内核的调试,主要还是在嵌入式板卡上用的比较多,需要掌握一个概念交叉编译,这个是玩嵌入式的必备概念,通俗点讲,在主机电脑上将程序编译好 1.生成的调试库以及驱动ko文件都会比较大,所以准备的磁盘空间至少20G左右 2.需要让内核支持支持kgdb调试功能,需要打开配置开关,正常的编译内核用make menuconfig,进入kernel
五、内核调试器 kgdb:像 gdb 一样调试内核 如果 printk 和 Oops 分析还不够,就需要kgdb—— 内核版的 gdb 调试器,支持断点、单步执行等高级调试功能。 5.1 搭建 kgdb 环境 kgdb 需要两台机器(或虚拟机)通过串口连接: 目标机:运行待调试的内核和模块 主机:运行 gdb,通过串口控制目标机 配置步骤(以虚拟机为例): 给目标虚拟机添加一个串口设备 目标机内核启动参数添加:kgdboc=ttyS0,115200 kgdbwait(启动时等待调试连接) 主机通过screen连接串口:screen /dev/ttyS0 115200 5.2 使用 kgdb break my_module_init # 查看变量 (gdb) print buffer_size # 单步执行 (gdb) step # 继续执行 (gdb) continue 5.3 kgdb 记住: 从简单工具开始:先用 printk 和 dmesg 解决 80% 的问题 善用系统提供的调试机制:动态调试、kmemleak 等内核自带工具 复杂问题才需要 kgdb:简单问题用高级工具反而效率低
KGDB是Linux内核的源代码级调试器,你可以使用GDB作为KGDB的前端,在我们熟悉且功能强大的GDB调试界面中调试内核。 使用KGDB需要两台机器,一台作为开发机,另一台是目标机器,要调试的内核在目标机器上运行。在开发机上使用gdb运行包含符号信息的vmlinux,然后通过指定网络地址和端口,连接到目标机器的KGDB。 我们也可以使用QEMU/KVM虚拟机作为目标机器,让待调试的内核运行在虚拟机中,然后在宿主机上运行gdb,连接到虚拟机中的KGDB。 CONFIG_GDB_SCRIPTS=y CONFIG_DEBUG_INFO_REDUCED=n CONFIG_KGDB 启用内置的内核调试器,该调试器允许进行远程调试。 CONFIG_KGDB=y 关闭CONFIG_RANDOMIZE_BASE设置 CONFIG_RANDOMIZE_BASE=n KASLR会更改引导时放置内核代码的基地址。
调试工具 Linux下的GNU调试工具主要是gdb、gdbserver和kgdb。其中gdb和gdbserver可完成对目标板上Linux下应用程序的远程调试。 对于Linux内核的调试,可以采用kgdb工具,同样需要通过串口与上位机上的gdb通信,对目标板的Linux内核进行调试。 可以从http://oss.sgi.com/projects/kgdb/上了解具体的使用方法。 参考资料: 1.
异常处理的注册 异常处理的注册在arch/arm64/kernel/debug-monitors.c, 是arm64的通用debug模块,kgdb也基于这个模块。 Appendix ARM64 BRK 指令 IMM16是自定义的,用于标识是哪种brk用途,比如kgdb或者kprobe。 主要使用的几个BRK立即数定义如下 #define FAULT_BRK_IMM 0x100 #define KGDB_DYN_DBG_BRK_IMM 0x400 #define KGDB_COMPILED_DBG_BRK_IMM 0x401 #define BUG_BRK_IMM 0x800 #define BRK64_ESR_KPROBES (AARCH64_BREAK_MON | (KGDB_DYN_DBG_BRK_IMM << 5)) ABI 写kprobe驱动要知道函数参数和寄存器的对应关系,需要了解对应体系架构的ABI (Application
在后面的kgdb开发中,不管是开发机,还是目标机,都需要禁止内核地址随机化。禁止的方法,即修改grub配置文件。
CONFIG_OVERWRITE_ETHADDR_ONCE #define CONFIG_BOOTCOMMAND "tftp 0x30008000 zImage;bootm" #if defined(CONFIG_CMD_KGDB ) #define CONFIG_KGDB_BAUDRATE 115200 /* speed to run kgdb serial port */ /* what's this it's not used anywhere */ #define CONFIG_KGDB_SER_INDEX 1 /* which serial port to use
调试与移植:内核开发的双翼调试工具链决定问题定位效率:printk基础但易影响时序;Oops/Panic信息是分析崩溃的关键;ftrace可追踪函数调用、中断延迟;initcall_debug用于启动优化;kgdb
内核调试:学习使用内核调试工具(如kgdb、kdb等),进行内核调试和故障排查。 4.2.
"\bprobe_ke" ffffffff811a5f00 W probe_kernel_read ffffffff811a5fc0 W probe_kernel_write 搜一下KDB/KGDB
手动检查更新sudo canonical-livepatch refresh内核热补丁技术细节:使用ftrace基础设施拦截函数调用确保补丁应用的内存安全性处理正在执行的函数实例7.2 内核调试与性能剖析使用kgdb 进行内核调试:# 配置内核支持kgdb# Kernel hacking -> KGDB: kernel debugger# 启动参数添加kgdboc(kgdb over console)kgdboc=ttyS0,115200
外的所有进程发出 SIGTERM 信号 echo f > /proc/sysrq-trigger 调用 oom_kill 杀死内存的 hog 进程 echo g > /proc/sysrq-trigger kgdb
这些都是可以帮助快速获取地址的, 上一篇文章说的kgdb工具也是可以的, 就是麻烦一点, 你懂的.
之前学习了利用KGDB双机调试内核,这种方式需要在两个主机上,通过串口线进行连接,或者是通过VMware开启两个虚拟机进行调试,对机器要求相对高一些。
扩展性:轻松支持新硬件和新功能 学习价值:理解内核机制的最佳切入点 6.2 潜在风险 稳定性风险:错误的模块代码可能导致内核崩溃(俗称 "Oops") 调试难度:内核态调试比用户态复杂(需用 kgdb 避免使用全局变量(模块间可能引发命名冲突) 8.2 调试技巧 printk日志:通过不同日志级别(KERN_DEBUG/KERN_ERR)定位问题 内核调试工具: dmesg:查看内核日志 kgdb
这之后,可以执行命令“make menuconfig”,在图形界面中对.config文件进行配置,按默认的配置就行(kgdb也默认配置好了),直接选择load,选择保存退出即可。