print_hex_dump调试内核,嘎嘎香

     本文首发于我的公众号 皮塞作坊 专注于干货分享,号欢迎大家关注,二维码文末可以扫。

     公众号:  使用print_hex_dump调试内核/驱动,太香了

最近在验证芯片功能的过程中发现了一个好用的内核调试接口,print_hex_dump,除了直接打印16进制和ascii外,还支持动态调试打印,uboot和内核中都有该函数的实现。

1.函数功能与用途

print_hex_dump是 Linux 内核中的一个函数,用于以十六进制和 ASCII 码格式打印内存数据块。它提供了一种方便的方式来查看和调试内核中的二进制数据。下面是函数原型:

void print_hex_dump(const char *level, const char *prefix_str, int prefix_type,
		    int rowsize, int groupsize,
		    const void *buf, size_t len, bool ascii)
{
	const u8 *ptr = buf;
	int i, linelen, remaining = len;
	unsigned char linebuf[32 * 3 + 2 + 32 + 1];

	if (rowsize != 16 && rowsize != 32)
		rowsize = 16;

	for (i = 0; i < len; i += rowsize) {
		linelen = min(remaining, rowsize);
		remaining -= rowsize;

		hex_dump_to_buffer(ptr + i, linelen, rowsize, groupsize,
				   linebuf, sizeof(linebuf), ascii);

		switch (prefix_type) {
		case DUMP_PREFIX_ADDRESS:
			printk("%s%s%p: %s\n",
			       level, prefix_str, ptr + i, linebuf);
			break;
		case DUMP_PREFIX_OFFSET:
			printk("%s%s%.8x: %s\n", level, prefix_str, i, linebuf);
			break;
		default:
			printk("%s%s%s\n", level, prefix_str, linebuf);
			break;
		}
	}
}

参数解释:

@level: 内核log级别 (e.g. KERN_DEBUG)

@prefix_str: 打印的前缀字符串

@prefix_type: 地址的输出格式是按照偏移、绝对地址或者不输出地址 (%DUMP_PREFIX_OFFSET, %DUMP_PREFIX_ADDRESS, %DUMP_PREFIX_NONE)

@rowsize: 每行印输出字节数; must be 16 or 32

@groupsize: 每次打印多少字节 (1, 2, 4, 8; default = 1)

@buf: 打印的数据地址

@len: 要打印数据长度

@ascii: 是否输出ascii码

2. 示例

在调试内核模块间传递的数据时,通过打印数据的十六进制和 ASCII 码表示,能够更直观地分析数据内容和格式是否符合预期

一次打印1字节,共打印32字节:

print_hex_dump(KERN_DEBUG, "show: ", DUMP_PREFIX_ADDRESS, 16, 1,bar_addr, 32, true);

 输出打印现象:

一次打印2字节,共打印64字节:

print_hex_dump(KERN_DEBUG, "show: ", DUMP_PREFIX_ADDRESS, 16, 2,bar_addr, 64, true);

 

3.动态调试

除此之外print_hex_dump_debug还支持动态调试,在这之前我们先了解下什么是动态调试。

这功能牛逼极了,我们不再需要为了添加了调试代码,而重新编译安装内核/驱动。你可以指定 CONDIF_DYNAMIC_DEBUG 选项打开动态调试功能,然后通过 /sys/kernel/debug/dynamic_debug/control 接口指定要打印哪些调试日志。

1. mkdir /mnt/dbg

2. mount -t debugfs none /mnt/dbg 默认挂载在/sys/kernel/debug/下

3.控制某个文件所有输出dev_dbg()、print_hex_dump_debug

echo -n "file xxx.c +p" > /mnt/dbg/dynamic_debug/control

4.控制某个函数所有dev_dbg(),print_hex_dump_debug

echo -n "func xxx +p" > /mnt/dbg/dynamic_debug/control

运行程序,使用dmesg则可以看到相应dev_dbg()的输出信息。

5.当调试结束,不再想输出dev_dbg()信息了,使用下面命令关闭即可

echo -n "file xxx.c -p" > /mnt/dbg/dynamic_debug/control

echo -n "func xxx -p" > /mnt/dbg/dynamic_debug/control

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

木泽八

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值