在 printk 中使用 %p 格式占位符用於列印指針值,但其行為與用戶空間的 printf 不同,默認會對地址進行哈希處理,以防止洩露內核內存布局的敏感信息。
%p 的行為
默認哈希:%p 不會直接列印指針的真實內存地址,而是輸出一個經過哈希處理的值。例如:abcdef12 或 00000000abcdef12(在64位系統上,高32位通常被清零)。
安全目的:這是內核的安全機制,避免攻擊者通過內核日誌獲取真實地址,從而利用內存漏洞。
唯一標識符:哈希後的值仍能作為該指針的唯一標識符,便於調試時追蹤對象。
如何列印真實地址?
如果調試時需要查看指針的真實內核虛擬地址,應使用以下替代格式:
%px:推薦方式,直接列印指針的原始值,無需強制類型轉換。例如:
cCopy Code
pr_info("Real address: %px\n", my_pointer);
輸出示例:0xffffff8018f4b000(符合ARM64內核地址空間規範)
%lx:可作為備選,但需將指針顯式轉換為 unsigned long:
cCopy Code
pr_info("Real address: 0x%lx\n", (unsigned long)my_pointer);
雖然能輸出正確地址,但不如 %px 簡潔且易被工具(如 grep)識別。
其他相關指針格式
格式
用途
示例輸出
%pS
列印符號名 + 偏移(帶函數名)
virtio_init+0x0/0x110
%ps
列印符號名(不帶偏移)
virtio_init
%pB
列印棧回溯用的符號名(考慮尾調用優化)
prev_fn+0x88/0x88
%pK
列印內核指針(僅用於 procfs/sysfs,需權限)
0x...
%pe
列印錯誤指針(如 -ENOSPC)
-ENOSPC
總結
不要用 %p 查看真實地址 → 會輸出哈希值。
調試內核地址時,優先使用 %px → 安全、直接、推薦。
僅在需要符號信息時使用 %pS 或 %pB → 更具語義價值。
⚠️ 注意:在用戶空間程序中,%p 會列印真實虛擬地址,但在內核空間中,安全策略強制哈希,這是有意設計,而非 bug。