arm linux内核调试器--kdb
来源:互联网 发布:三菱plcfx3u编程实例 编辑:程序博客网 时间:2024/05/05 15:22
0x1. 介绍
kdb是简单主义的shell风格的交互接口,可以借助键盘或者串口在系统终端上使用。你可以用它查看内存,寄存器,进程列表,内核log,甚至设置断点停在某个地方,尽管你可以设置断点并且对内核运行进行简单的控制,但kdb不是源码级的调试器。kdb主要的目标时对内核做一些分析用于辅助开发和诊断内核问题。如果内核编译时选择了CONFIG_KALLSYMS,不管时内建的还是模块编译,都可以通过名称访问内核符号,例如可以通过bp命令传入函数符号设置断点等。
0x2. 优势
单机调试,嵌入式平台利用调试串口作为kdb I/O driver很方便
0x3. 使用方法
0x31. 配置内核
为了使能KDB,要先使能KGDB
CONFIG_KGDB=y
打开kgdb的时候包含kdb调试器
CONFIG_KGDB_KDB=y
CONFIG_DEBUG_RODATA选项会标记某些内存区域为只读属性,影响软件断点的使用,这时候需要关闭。如果处理器支持硬件断点,该选项可以打开
#CONFIG_DEBUG_RODATA is not set
CONFIG_FRAME_POINTER选项更好的支持栈回溯,该选项依赖于CONFIG_HAVE_FUNCTION_GRAPH_TRACER
CONFIG_FRAME_POINTER=y
CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
CONFIG_KGDB_SERIAL_CONSOLE选项确定串口为kdb的I/O driver
CONFIG_KGDB_SERIAL_CONSOLE=y
0x32. 激活kdb
内核启动参数:
kgdboc=,[baud]
示例1:
添加到内核引导参数
kgdboc=ttyAMA0,115200
或者运行时激活
echo > /sys/module/kgdboc/parameters/kgdboc
运行时关闭
echo “” > /sys/module/kgdboc/parameters/kgdboc
示例2:
运行时激活
echo ttyAMA0 > /sys/module/kgdboc/parameters/kgdboc
0x33. 进入kdb模式
发生oops或fault触发kdb。或者手动进入kdb shell或,手动进入命令:
echo g > /proc/sysrq-trigger
使用sysrq的前提是CONFIG_MAGIC_SYSRQ=y
0x34. 基本命令
进入kdb shell后可以使用如下命令:
lsmod – 显示内核加载的模块
ps – 显示活动的进程
ps A – 显示所用的进程
summary – 显示内核版本信息和内存使用情况
bt – 调用 dump_stack()函数查看当前进程的回溯信息
dmesg – 查看内核log
go – 系统继续执行
reboot 命令立刻重新引导系统。它并没有彻底关闭系统,因此结果是不可预测的。
内存操作命令
md 命令以一个地址/符号和行计数为参数,显示从该地址开始的 line-count 行的内存。
mm 命令修改内存内容。
常用的断点命令
bp 命令以一个地址/符号作为参数,它在地址处应用断点
bd 命令禁用特殊断点,它接收断点号作为参数。该命令不是从断点表中除去断点,而只是禁用它。断点号从 0 开始,根据可用性顺序分配给断点。
be 命令启用断点。该命令的参数也是断点号
bl 命令列出当前的断点集。它包含了启用的和禁用的断点。
bc 清除断点。它以具体的断点号或 * 作为参数,在后一种情况下它将除去所有断点
0x44. 调试技巧
0x41. gdb辅助调试
gdb启动时加载内核符号
arm-none-linux-gnueabi-gdb vmlinux
加载模块符号
add-symbol-file test_panic.ko ADDR_FROM_LSMOD
查找panic位置
info line *0xADDR_FROM_BT
显示panic位置
list linenum
0x42. 内核符号与地址
要在运行时查看内核符号,内核需要配置CONFIG_KALLSYMS=y和CONFIG_KALLSYMS_ALL=y。进入kdb后,输入地址可以获取符号信息,输入符号可以获取地址信息
0x5. 测试环境
0x51. 版本信息
linux版本号: 4.10.9
交叉编译工具版本:
arm-none-linux-gnueabi-gcc (Sourcery CodeBench Lite 2014.05-29) 4.8.3
arm-none-linux-gnueabi-gdb GNU gdb (Sourcery CodeBench Lite 2014.05-29) 7.7.50.20140217-cvs
qemu版本:QEMU emulator version 2.7.1
模拟开发板:arm vexpress a9
0x52. 测试代码
/* * Copyright (c) 2005-2010 Wind River Systems, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. */#include <linux/module.h>#include <linux/delay.h>#include <linux/moduleparam.h>#include <linux/types.h>#include <linux/timer.h>#include <linux/miscdevice.h>#include <linux/watchdog.h>#include <linux/fs.h>#include <linux/notifier.h>#include <linux/reboot.h>#include <linux/init.h>#include <linux/proc_fs.h>#include <linux/sched.h>#include <asm/uaccess.h>#include <linux/slab.h>#define LOCAL_MODULE_VERSION "1.0"#define MODULE_NAME "test_panic"#define DEAD_ADDRESS 0xdeadbeefstatic struct proc_dir_entry *panic_dir;static struct proc_dir_entry *panic_file;static struct proc_dir_entry *test_file;static struct proc_dir_entry *print_file;static int panic_proc_open(struct inode *inode, struct file *file){ int err = 0; if (try_module_get(THIS_MODULE)) { return err; } return -ENODEV;}static int panic_proc_release(struct inode *inode, struct file *file){ module_put(THIS_MODULE); return 0;}static ssize_t panic_proc_write(struct file *file, const char __user *buffer, size_t count, loff_t *data){ trace_printk("Starting panic\n"); printk(KERN_INFO "=============Starting panic\n"); panic("test_panic running!\n"); return count;}static int test_aaa = 0;static int *test_addr = NULL;static ssize_t test_proc_write(struct file *file, const char __user *buffer, size_t count, loff_t *data){ printk(KERN_INFO "test_aaa = 0x%08x\n", test_aaa); test_addr = &test_aaa; return count;}static ssize_t print_proc_write(struct file *file, const char __user *buffer, size_t count, loff_t *data){ printk(KERN_INFO "enter printk\n"); return count;}static const struct file_operations panic_fops = { .owner = THIS_MODULE, .open = panic_proc_open, .write = panic_proc_write, .release = panic_proc_release,};static const struct file_operations test_fops = { .owner = THIS_MODULE, .write = test_proc_write,};static const struct file_operations print_fops = { .owner = THIS_MODULE, .write = print_proc_write,};static int __init test_panic_init(void){ int rc = -ENOMEM; trace_printk("Running test_panic_init()"); /* create directory */ panic_dir = proc_mkdir(MODULE_NAME, NULL); if(!panic_dir) return rc; trace_printk("test_panic: Building panic\n"); panic_file = proc_create("panic", S_IFREG | S_IRUGO | S_IWUSR, panic_dir, &panic_fops); if(!panic_file) goto fail1; test_file = proc_create("test", S_IFREG | S_IRUGO | S_IWUSR, panic_dir, &test_fops); if(!panic_file) goto fail2; print_file = proc_create("print", S_IFREG | S_IRUGO | S_IWUSR, panic_dir, &print_fops); if(!panic_file) goto fail3; trace_printk(KERN_INFO "%s %s initialised\n", MODULE_NAME, LOCAL_MODULE_VERSION); printk(KERN_INFO "%s %s initialised\n", MODULE_NAME, LOCAL_MODULE_VERSION); return 0;fail3: remove_proc_entry("test", panic_dir);fail2: remove_proc_entry("panic", panic_dir);fail1: remove_proc_entry(MODULE_NAME, NULL); return rc;}static void __exit test_panic_exit(void){ remove_proc_entry("panic", panic_dir); remove_proc_entry("test", panic_dir); remove_proc_entry("print", panic_dir); remove_proc_entry(MODULE_NAME, NULL); printk(KERN_INFO "%s %s removed\n", MODULE_NAME, LOCAL_MODULE_VERSION);}module_init(test_panic_init);module_exit(test_panic_exit);MODULE_DESCRIPTION("base on WindRiver code");MODULE_AUTHOR("marquis song");MODULE_LICENSE("GPL v2");
0x53. qemu参数
qemu-system-arm \ -M vexpress-a9 \ -kernel ~/src/linux/kernel/vexpress-a9-linux-4.10.9/arch/arm/boot/zImage \ -dtb ~/src/linux/kernel/vexpress-a9-linux-4.10.9/arch/arm/boot/dts/vexpress-v2p-ca9.dtb \ -sd ~/src/qemu/image/rootfs.ext4 \ -nographic -append "root=/dev/mmcblk0 rw rootfstype=ext4 rootwait init=/linuxrc rootdelay=3 physmap.enabled=0 console=ttyAMA0 kgdboc=ttyAMA0,115200"
参考资料
https://kgdb.wiki.kernel.org/index.php/Main_Page
https://www.kernel.org/pub/linux/kernel/people/jwessel/kdb/index.html
https://www.kernel.org/pub/linux/kernel/people/jwessel/dbg_webinar/State_Of_kernel_debugging_LinuxCon2014.pdf
https://www.ibm.com/developerworks/cn/linux/l-kdbug/
- arm linux内核调试器--kdb
- Linux 内核调试器内幕 —— KDB 入门指南
- linux系统通过内核调试器kdb获取root权限
- Linux内核调试工具:Kdb应用指南
- linux 内核调试--KDB 入门指南
- 用kdb调试linux内核驱动
- 用kdb调试linux内核驱动
- linux内核编译调试工具KDB入门
- 用kdb调试linux内核驱动
- 配置串口使用KDB调试Linux内核
- kdb 调试内核
- Linux内核:安装kdb
- Linux内核调试工具:Kdb的编译安装
- 在vmware中用kdb调试linux内核和模块
- 使用kdb和kgdb调试Linux内核(1)
- 使用kdb和kgdb调试Linux内核(2)
- 使用kdb和kgdb调试Linux内核(3)
- Linux KDB 调试1
- 一带一路
- Vim光标跳转(函数跳转)
- 为RecyclerView添加精美的分割线
- 提高Html5性能的方法
- 使用v-if v-else发现没有执行
- arm linux内核调试器--kdb
- XUtils 3 之 了解
- 今天挺晚的,十点多了。
- C++第五次上机实验——数组分离
- VR系列——Oculus Rift 开发者指南:一、LibOVR集成
- ionic-下拉刷新载入数据
- python读取网页
- 浙大校赛- Course Selection System
- Struts2(二)——配置文件struts2.xml的编写