在 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。
