HWAddress Sanitizer

透過集合功能整理內容 你可以依據偏好儲存及分類內容。

從 NDK r21 和 Android 10 (API 級別 29) 開始,Android NDK 支援 HWAddress Sanitizer (又稱為 HWASan)。HWASan 僅適用於 64 位元 Arm 裝置。

HWASan 是一款與 ASan 相似的記憶體錯誤偵測工具。相較於傳統 ASan,HWASan 具備以下特點:

  • CPU 負擔相近 (約 2 倍)
  • 程式碼大小負擔相近 (40 - 50%)
  • RAM 負擔大幅減少 (10% - 35%)

HWASan 能夠偵測 ASan 可偵測到的錯誤:

  • 堆疊和堆積緩衝區溢位/反向溢位
  • 釋放後的堆積使用情況
  • 超出範圍的堆疊使用情況
  • 重複釋放/錯誤釋放

此外,HWASan 也能偵測:

  • 傳回後堆疊的使用情況

設定

HWASan 應用程式需要 Android HWASan 版本,才能順利執行。您可以將預先建構的 HWASan 映像檔刷新至支援的 Pixel 裝置。您可在 ci.android.com 中找到這些建構內容,只要按一下確切建構內容 (正方形),即可取得刷新建構連結。為此,您必須知道手機的產品代號

刷新裝置建構

更簡單的做法是直接造訪 flash.android.com,因為在這個作業流程中,系統會從偵測裝置開始,並僅列出您可以使用的建構內容。 下圖說明這項工具的設定流程。

在裝置上啟用開發人員模式,然後透過 USB 傳輸線將裝置連接至電腦。按一下「Add new device」(新增裝置),從對話方塊中選取您的裝置,然後按一下「Connect」(連接)

偵測要刷新的裝置 選取要連接的裝置

連接裝置後,您必須按一下該裝置才能設定建構作業。 在「Select a build ID」(選取建構作業 ID) 方塊中,選取 aosp-master-with-phones-throttled 分支版本,讓系統自動為已連接的裝置選擇正確的映像檔。

選取要刷新的裝置 確認刷新選項並刷新裝置

按一下「Install」(安裝) 即可刷新裝置。

如要進一步瞭解必要的設定,請參閱 Android Flash Tool 說明文件。另外,您也可以參閱 Android 開放原始碼計畫說明文件,瞭解如何從來源建構 HWASan 映像檔。

建構

如要透過 HWAddress Sanitizer 建構應用程式的原生 (JNI) 程式碼,請按照下列指示操作:

ndk-build

Application.mk 檔案中:

APP_STL := c++_shared # Or system, or none, but not c++_static.
APP_CFLAGS := -fsanitize=hwaddress -fno-omit-frame-pointer
APP_LDFLAGS := -fsanitize=hwaddress

CMake

在模組的 build.gradle 檔案中:

android {
    defaultConfig {
        externalNativeBuild {
            cmake {
                # Can also use system or none as ANDROID_STL, but not c++_static.
                arguments "-DANDROID_STL=c++_shared"
            }
        }
    }
}

針對 CMakeLists.txt 中的每個目標:

target_compile_options(${TARGET} PUBLIC -fsanitize=hwaddress -fno-omit-frame-pointer)
set_target_properties(${TARGET} PROPERTIES LINK_FLAGS -fsanitize=hwaddress)

執行

依照平常的方法在以 HWASan 建構的 Android 映像檔上執行應用程式。系統偵測到記憶體錯誤時,應用程式會因 SIGABRT 而異常終止,並輸出詳細的訊息至 logcat。您可以在 /data/tombstones 下的檔案中找到這則訊息的副本,內容如下所示:

ERROR: HWAddressSanitizer: tag-mismatch on address 0x0042a0826510 at pc 0x007b24d90a0c
WRITE of size 1 at 0x0042a0826510 tags: 32/3d (ptr/mem) in thread T0
    #0 0x7b24d90a08  (/data/app/com.example.hellohwasan-eRpO2UhYylZaW0P_E0z7vA==/lib/arm64/libnative-lib.so+0x2a08)
    #1 0x7b8f1e4ccc  (/apex/com.android.art/lib64/libart.so+0x198ccc)
    #2 0x7b8f1db364  (/apex/com.android.art/lib64/libart.so+0x18f364)
    #3 0x7b8f2ad8d4  (/apex/com.android.art/lib64/libart.so+0x2618d4)

0x0042a0826510 is located 0 bytes to the right of 16-byte region [0x0042a0826500,0x0042a0826510)
allocated here:
    #0 0x7b92a322bc  (/apex/com.android.runtime/lib64/bionic/libclang_rt.hwasan-aarch64-android.so+0x212bc)
    #1 0x7b24d909e0  (/data/app/com.example.hellohwasan-eRpO2UhYylZaW0P_E0z7vA==/lib/arm64/libnative-lib.so+0x29e0)
    #2 0x7b8f1e4ccc  (/apex/com.android.art/lib64/libart.so+0x198ccc)

訊息後面可能會附加額外的偵錯資訊,例如列出應用程式中正在使用的執行緒、鄰近記憶體配置的標記、CPU 註冊值等。

如要進一步瞭解 HWASan 錯誤訊息,請參閱瞭解 HWASan 報告