請參閱瞭解 HWASan 報表,瞭解如何讀取 HWASan 當機情形!
Hardware-assisted AddressSanitizer (HWASan) 是一款與 AddressSanitizer 相似的記憶體錯誤偵測工具。HWASan 與 ASan 相比,RAM 大幅減少,因此適合 整個系統清理作業HWASan 僅適用於 Android 10 以及更高版本,且僅適用於 AArch64 硬體
雖然 HWASan 主要用於 C/C++ 程式碼,但也可以協助偵錯會導致 C/C++ 在實作 Java 介面時發生當機的 Java 程式碼。這項功能可以擷取回憶集錦 錯誤時,系統會直接指出負責的程式碼。
您可以從 ci.android.com 將預先建構的 HWASan 映像檔刷新至支援的 Pixel 裝置 (詳細設定操作說明)。
相較於傳統 ASan,HWASan 具備以下特點:
- 額外占用的 CPU 資源相近 (約 2 倍)
- 額外占用程式碼的空間相近 (40 - 50%)
- 額外占用的 RAM 大幅減少 (10% - 35%)
HWASan 能夠偵測 ASan 可偵測到的錯誤:
- 堆疊和堆積緩衝區溢位/反向溢位
- 釋放後的堆積使用情況
- 超出範圍的堆疊使用情況
- 重複釋放/錯誤釋放
此外,HWASan 也會偵測傳回後的堆疊使用情況。
HWASan (與 ASan) 相容 UBSan、 這兩項功能可以同時在目標上啟用
實作詳情和限制
HWASan 是以記憶體標記方法為基礎,其中小型隨機標記值會與指標和記憶體位址範圍相關聯。回憶集錦 指標和記憶體標記必須相符。 HWASan 會使用 ARMv8 功能的 Top Byte Ignore (TBI),也稱為虛擬位址標記,在位址最高位元中儲存指標標記。
如要進一步瞭解 HWASan 的設計,請前往 Clang 說明文件網站。
在設計上,HWASan 不會有 ASan 的限量紅區域 偵測溢位現象或 ASan 的有限容量隔離區 偵測免費後的使用情況因此,HWASan 能夠偵測 無論溢位多少 已分配。因此 HWASan 優於 ASan。
不過,HWASan 的標記值數量有限 (256),這表示在執行程式期間,錯過任何錯誤的機率為 0.4%。
需求條件
Android 通用核心的最新版本 (4.14 以上) 支援即時啟用的 HWASan。Android 10 專屬分支版本不支援 HWASan。
自 Android 11 起,HWASan 可提供使用者空間支援。
如果您要使用其他核心,HWASan 需要 Linux kernel,才能接受在 系統呼叫引數我們已在下列上游修補集中實作此功能的支援:
- arm64 標記位址 ABI
- arm64:傳遞至核心的未標記使用者指標
- mm:避免在 brk()/mmap()/mremap() 中建立虛擬位址別名
- arm64:驗證 access_ok() 中從核心執行緒呼叫的已標記位址
如果您使用自訂工具鏈進行建構,請確認該工具鏈包含 LLVM 提交版本 c336557f 的所有內容。
使用 HWASan
請使用下列指令,使用 HWASan 建構整個平台:
lunch aosp_walleye-userdebug # (or any other product)
export SANITIZE_TARGET=hwaddress
m -j
為了方便起見,您可以在產品定義中加入 SANITIZE_TARGET 設定。 類似 aosp_coral_hwasan。
對於熟悉 AddressSanitizer 的使用者來說,許多建構複雜性都已消失:
- 無須執行兩次。
- 漸進式建構作業可立即使用。
- 不需要閃記使用者資料。
部分 AddressSanitizer 限制也會一併移除:
- 支援靜態執行檔。
- 您可以略過 libc 以外的任何目標的清理作業。與 ASan 不同的是,如果程式庫經過消毒處理,則連結該程式庫的任何可執行檔不一定要經過消毒處理。
您可以自由切換相同 (或更高) 版本號碼的 HWASan 和一般映像檔。無須清除裝置。
如要略過模組的清理作業,請使用
LOCAL_NOSANITIZE := hwaddress
(Android.mk) 或
sanitize: { hwaddress: false }
(Android.bp)。
清理個別目標
只要 libc.so
消毒。將 hwaddress: true
新增至 "libc_defaults"
中的清理區塊
Bnic/libc/Android.bp。然後對著目標進行同樣的操作。
請注意,清理 libc 可讓您標記整個系統的堆積記憶體配置,以及
檢查 libc.so
內記憶體作業的標記。即使在未啟用 HWASan 的二進位檔中,如果 libc.so
有錯誤的記憶體存取行為,這項功能也可能會偵測到錯誤 (例如 pthread_mutex_unlock()
(在 delete()
互斥鎖上)。
如果整個平台是以 HWASan 建構而成,則無需變更任何建構檔案。
閃電所
為了開發目的,您可以使用 Flashstation,將支援 HWASan 的 AOSP 版本刷新至 bootloader 已解鎖的 Pixel 裝置。選取 _hwasan 目標,例如:aosp_flame_hwasan-userdebug如需詳細資訊,請參閱應用程式開發人員的 NDK 說明文件,瞭解 HWASan 的相關資訊。
更完善的堆疊追蹤
HWASan 會使用快速的框架指標型解開器,為程式中的每個記憶體配置和取消配置事件記錄堆疊追蹤。Android 預設會在 AArch64 程式碼中啟用影格指標,因此在實際操作中運作良好。如果您需要透過受管理的程式碼解開,請在程序環境中設定 HWASAN_OPTIONS=fast_unwind_on_malloc=0
。請注意,記憶體存取堆疊錯誤
追蹤記錄會使用「慢速」預設為展開模式;這項設定只會影響
配置和交易配置追蹤記錄建議您
耗用大量 CPU 資源,視負載量而定。
符號化
請參閱「符號化」 「瞭解 HWASan 報告」一節。
應用程式中的 HWASan
與 AddressSanitizer 類似,HWAsan 無法查看 Java 程式碼,但可以偵測 JNI 程式庫中的錯誤。在 Android 14 之前,系統不支援在非 HWASan 裝置上執行 HWASan 應用程式。
在 HWASan 裝置上,您可以使用 HWASan 檢查應用程式,方法是在 Make 中使用 SANITIZE_TARGET:=hwaddress
建構應用程式程式碼,或是在編譯器標記中使用 -fsanitize=hwaddress
。在非 HWASan 裝置 (搭載 Android 14 以上版本) 上,必須新增 wrap.sh 檔案設定 LD_HWASAN=1
。詳情請參閱應用程式開發人員說明文件。