AddressSanitizer 陰影位元組
我們簡短摘要說明陰影位元組的概念,以及 執行時間實 /fsanitize=address
作如何使用它們。 如需進一步的詳細資料,請參閱 開創性論文 和 AddressSanitizer 演算法 。
核心概念
您可以使用一個陰影位元組來描述您應用程式虛擬位址空間中的每 8 個位元組 。
一個陰影位元組描述目前可存取的位元組數目,如下所示:
- 0 表示所有 8 個位元組
- 1-7 表示一到七個位元組
- 負數編碼執行時間用於報告診斷的內容。
陰影位元組圖例
請考慮定義所有負數的這個陰影位元組圖例:
對應 - 描述您的位址空間
應用程式虛擬位址空間中對齊 「0-mod-8」 的每個 8 個位元組,都可以對應至描述虛擬位址空間中該位置的陰影位元組。 此對應可以透過簡單的移位和新增 來完成 。
在 x86 上:
char shadow_byte_value = *((Your_Address >> 3) + 0x30000000)
在 x64 上:
char shadow_byte_value = *((Your_Address >> 3) + _asan_runtime_assigned_offset)
程式碼產生 - 測試
請考慮編譯器產生的程式碼、靜態資料或執行時間可能會寫入特定陰影位元組的方式。 此虛擬程式碼示範如何產生任何負載或存放區前面的檢查:
ShadowAddr = (Addr >> 3) + Offset;
if (*ShadowAddr != 0) {
ReportAndCrash(Addr);
}
檢測小於 8 個位元組的記憶體參考時,檢測會稍微複雜一點。 如果陰影值是正數(這表示只能存取 8 位元組字中的第一個 K 位元組),我們需要比較位址的最後 3 位與 k。
ShadowAddr = (Addr >> 3) + Offset;
k = *ShadowAddr;
if (k != 0 && ((Addr & 7) + AccessSize > k)) {
ReportAndCrash(Addr);
}
執行時間和編譯器產生的程式碼都會寫入陰影位元組。 當範圍結束或儲存體釋出時,這些陰影位元組會允許或撤銷存取權。 上述檢查會讀取陰影位元組,以描述應用程式位址空間中的 8 位元組「位置」,在程式執行的特定時間。 除了這些明確產生的檢查之外,執行時間也會在攔截 CRT 中的許多函式之後檢查陰影位元組。
如需詳細資訊,請參閱攔截的 函 式清單。
設定陰影位元組
編譯器產生的程式碼和 AddressSanitizer 執行時間都可以寫入陰影位元組。 例如,編譯器可以設定陰影位元組,以允許固定大小的存取內部範圍中定義的堆疊區域變數。 執行時間可以使用陰影位元組括住資料區段中的全域變數。
另請參閱
AddressSanitizer 概觀
AddressSanitizer 已知問題
AddressSanitizer 組建和語言參考
AddressSanitizer 執行時間參考
AddressSanitizer 雲端或分散式測試
AddressSanitizer 偵錯工具整合
AddressSanitizer 錯誤範例
意見反應
https://aka.ms/ContentUserFeedback。
即將登場:在 2024 年,我們將逐步淘汰 GitHub 問題作為內容的意見反應機制,並將它取代為新的意見反應系統。 如需詳細資訊,請參閱:提交並檢視相關的意見反應