Linux内核调试必备:printk打印内存地址的5种姿势(附完整代码示例)
在Linux内核开发中,调试内存相关问题往往是最具挑战性的任务之一。当系统崩溃或出现异常行为时,能够准确获取和解读内存地址信息是定位问题的关键。不同于用户空间程序,内核环境对地址访问有更严格的限制和安全要求,这也使得内核中的地址打印成为一门需要专门掌握的技巧。
本文将深入探讨printk函数中五种不同的内存地址打印方法,每种方法都有其特定的使用场景和注意事项。无论你是正在开发内核模块的新手,还是需要调试复杂设备驱动的资深工程师,这些技巧都能帮助你更高效地获取关键调试信息。我们将通过实际代码示例展示如何安全、准确地打印虚拟地址、物理地址、函数指针以及内核符号信息。
1. 虚拟地址打印:%px与%pK的深度解析
虚拟地址是Linux内核开发中最常接触的地址类型,但直接打印裸指针可能带来安全隐患。内核提供了两种专门的格式说明符来处理虚拟地址:
void *vaddr = kmalloc(1024, GFP_KERNEL);
printk("Virtual address (raw): %px\n", vaddr);
printk("Virtual address (restricted): %pK\n", vaddr);
%px是最基础的虚拟地址打印格式,它会将指针值以十六进制形式输出,但相比直接使用%p,它增加了基本的安全性检查。值得注意的是:
- 在64位系统上,%px会输出完整的64位地址
- 在32位系统上,则输出32位地址
- 输出格式为
0x前缀加上小写十六进制数字
%pK则提供了更高级的安全控制,它的行为取决于kptr_restrict内核参数的设置:
| kptr_restrict值 | %pK输出行为 |
|---|

&spm=1001.2101.3001.5002&articleId=159361603&d=1&t=3&u=86baf71b5c0b44e89a879c881c3b40da)
2492

被折叠的 条评论
为什么被折叠?



