Linux驱动中%p与%x输出结果不同的原因探究
为什么%p和%x输出的地址不一样?
核心原因有两个:
1. 内核指针的安全混淆机制
Linux内核里用%p输出指针时,会触发kptr_restrict安全机制——默认情况下,它会对内核指针地址做随机化混淆,不会直接输出真实地址,目的是防止泄露内核地址空间布局,避免被利用发起攻击。你看到的32ba0e06是经过混淆后的假地址,不是变量c的真实内存地址。
2. 格式符与参数类型不匹配
%x是专门用来格式化int类型数据的,但你传入的&c是指针类型:
- 如果是64位系统,指针占8字节,
%x只会读取低4字节内容,所以输出的eef1ff1c只是真实地址的一部分; - 哪怕是32位系统,用
%x输出指针也是未定义行为,因为格式符和参数类型不匹配,结果完全不可靠。
正确的输出方式
如果需要在驱动里输出真实的指针地址,可以用这两种方法:
- 用内核特有的
%px格式符:它会输出指针的原始真实值,绕过kptr_restrict的混淆(注意需要对应权限,或者调整sysctl kernel.kptr_restrict参数); - 保证格式符和参数类型匹配:比如把指针转成
unsigned long类型,用%lx格式化。
修正后的代码示例:
pr_info("address %px %lx", &c, (unsigned long)&c);
内容的提问来源于stack exchange,提问作者sunhang
相关产品推荐
相关产品推荐

