本文說明如何在使用 AGDE 時啟用特殊偵錯工具。這些工具可找出難以診斷的記憶體毀損情形,並覆寫錯誤。
HWAddress Sanitizer 和 Address Sanitizer
HWAddress Sanitizer (HWASan) 和 Address Sanitizer (ASan) 是記憶體毀損偵錯工具,可偵測記憶體毀損情形並覆寫錯誤,例如以下情形:
- 堆疊緩衝區溢位和反向溢位
- 堆積緩衝區溢位和反向溢位
- 超出範圍的堆疊使用情形
- 重複釋放和野釋放錯誤
- 回傳後的堆疊使用情形 (僅限 HWASan)
建議您僅在偵錯或執行自動化測試時,才啟用 HWASan 或 ASan。這些工具雖然很有效,但使用時可能導致效能降低。
執行階段行為
HWASan 和 ASan 啟用時,會自動檢查整個應用程式執行階段的記憶體毀損情形。
如果偵測到記憶體錯誤,應用程式會因 SIGBART
(訊號取消) 錯誤異常終止,並將詳細訊息顯示在 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)
必要條件
安裝 Android 作業系統的 HWASan 版本
如要使用 HWASan,請按照 HWASan 說明文件中的設定操作說明,安裝 Google Pixel 裝置適用的 Android 作業系統 HWASan 版本。
若是其他裝置,請與製造商聯絡,取得該 OS 的 HWASan 版本 (如有),或使用軟體專用 ASan 工具。
在專案中使用共用 C++ 標準程式庫
由於某項已知問題的影響,使用 libc++_static
時,ASan 目前無法處理 C++ 例外狀況。使用 libc++_shared
時則不會發生這個問題。
HWASan 擁有專屬的運算子 new
和 delete
實作方法,如果標準程式庫是靜態連結至專案,就無法使用這些方法。
如要變更這項設定,請參閱本文件中的連結 C++ 標準程式庫相關說明。
啟用影格指標產生功能
HWASan 與 ASan 可使用快速影格指標型解開器,為記憶體配置和取消配置事件產生堆疊追蹤資訊。這代表您必須在 C++ 編譯器設定中啟用影格指標產生功能,才能使用這些功能。您也需要停用影格指標省略最佳化功能。
如要變更這項設定,請參閱本文件的「啟用影格指標產生功能」一節。
設定 Visual Studio 專案以使用 HWASan 或 ASan
啟用 HWASan 或 ASan
如要啟用 HWASan 或 ASan,請在專案的「Property Pages」中,依序點選「Configuration Properties」>「General」。
圖 1:專案在 Visual Studio「Solution Explorer」視窗中的「Properties」選項。
圖 2:一般專案屬性中的「Address Sanitizer (ASan)」設定。
如要為專案啟用 HWASan,請將「Address Sanitizer (ASan)」設定變更為「Hardware ASan Enabled (fsanitize=hwaddress)」。
如要為專案啟用 ASan,請將「Address Sanitizer (ASan)」設定變更為「ASan Enabled (fsanitize=address)」。
啟用影格指標產生功能
如要控管影格指標產生功能,需使用「Omit Frame Pointer」C/C++ 編譯器設定。在專案的「Property Pages」對話方塊中,依序選取「Configuration Properties」>「C/C++」>「Optimization」,即可存取這項設定。
圖 3:「Omit Frame Pointer」設定的位置。
使用 HWASan 或 ASan 時,請將「Omit Frame Pointer」設定設為「No (-fno-omit-frame-pointer)」。
在共用程式庫模式中連結 C++ 標準程式庫
在專案「Property Pages」對話方塊中,依序點選「Configuration Properties」>「General」,即可在「Project Defaults」部分找到 C++ 標準程式庫的連結器模式設定。
圖 4:C++ 標準程式庫連結器模式設定的位置。
使用 HWASan 或 ASan 時,請將「Use of STL」設為「Use C++ Standard libraries (.so)」。這個值會以「共用程式庫」的形式將 C++ 標準程式庫連結至專案,這是讓 HWASan 與 ASan 正常運作的必要步驟。
針對 Address Sanitizer 使用情形建立建構設定
如果您偏向「暫時」使用 HWASan 或 ASan,就不建議專為這項用途建立新的建構設定。當專案規模較小,或是您單純在瞭解這項功能或處理測試期間發現的問題時,就可能屬於這種情況。
不過,如果覺得這項功能很實用,且預計經常使用,則建議您考慮為 HWASan 或 ASan 建立新的建構設定,如 Teapot 範例所示。舉例來說,如果您會在單元測試或遊戲的整晚冒煙測試中定期執行 Address Sanitizer,就可以採用這種做法。
如果您的大型專案使用大量不同的第三方程式庫,而且這些程式庫通常是靜態連結至 C++ 標準程式庫,那另外建立建構設定就可能特別實用。專屬建構設定可隨時確保專案設定準確無誤。
如要建立建構設定,請按一下專案「Property Pages」中的「Configuration Manager…」按鈕,然後開啟「Active solution configuration」下拉式選單。接著請選取