Up to date

This page is up to date for Godot 4.2. If you still find outdated information, please open an issue.

建立內容

什麼是 Sanitizer?

Sanitizer 是一種靜態偵測工具,能夠説明找出傳統除錯器通常無法捕捉的問題。非常適合在持續集成中與 位元移位 結合使用。

在 Windows、macOS、Linux 平臺使用 Clang(LLVM)、GCC、Visual Studio 編譯器時能夠使用 Sanitizer。:ref:`部分平臺 <doc_using_sanitizers_platform_specific_sanitizers>`可能也可以使用其獨有的 Sanitizer。多種不同的編譯器都提供相同的某種 Sanitizer 時,請記住它們的輸出和行為有可能略有不同。

在 Godot 中使用 NuGet 套件

Sanitizer **要求**重新編譯二進位檔案。這意味著你無法使用官方 Godot 二進位檔案來運作 Sanitizer。

當在啟用任何消毒劑的情況下編譯 <toc-devel-compiling>` 時,生成的二進位檔案將在其名稱中新增``.san`` 後綴,以將其與沒有消毒劑的二進位檔案區分開來。

由於需要執行許多額外的運作時檢查,因此會對效能產生影響。記憶體利用率也會增加。可以在單一建構中啟用多種消毒劑的某些組合。不過,請注意同時使用多個消毒劑時的性能影響,因為生成的二進位可能會非常慢。

某些選項可以傳遞給清理程式,而無需使用環境變數重新編譯二進位。

地址 Sanitizer(ASAN)

  • 與其他腳本語言溝通

  • **支援的平臺:**Linux、macOS、Windows(Visual Studio)、Web

  • Clang ASAN 文件

地址消毒劑通常是最常用的消毒劑。它可以診斷緩衝區溢位和越界存取等問題。如果引擎當機並顯示諸如“free():無效指標”之類的訊息,這通常是緩衝區溢位的結果。 (此訊息是由 C 運作時列印的,而不是 Godot。)

在某些情況下(例如偵測未初始化的記憶體讀取),位址清理程式還不夠。應使用 記憶體 Sanitizer(MSAN) 來代替。

也可以透過在*執行* Godot 之前(而不是在編譯時)指定「ASAN_OPTIONS=detect_stack_use_after_return=1」環境變數來偵測返回後使用情況。這會增加地址清理程式的運作時開銷,因此僅在實際需要時才啟用此功能。

若要在 Godot 建置中啟用地址清理程式,請在編譯時傳遞“use_asan=yes”SCons 選項。啟用 ASAN 通常會使產生的二進位檔案變慢約 2 倍。

警告

由於“設計決策<https://stackoverflow.com/questions/36971902/why-cant-clang-enable-all-sanitizers/>”,位址、記憶體和執行緒清理器是互斥的。這意味著您只能在給定的二進位檔案中使用其中一種消毒劑。

洩漏 Sanitizer(LSAN)

洩漏清理程式可以偵測記憶體洩漏,即執行的程式永遠不會釋放不再使用的記憶體的情況。如果程式運作時間夠長,這可能會導致記憶體不足的情況。由於 Godot 可能會在專用伺服器 <doc_exporting_for_dedicated_servers>` 上運作數月甚至數年而無需重新啟動,因此在發生記憶體洩漏時修復記憶體洩漏非常重要。

若要在 Godot 建置中啟用洩漏清理程式,請在編譯時傳遞「use_lsan=yes」SCons 選項。啟用LSAN只會有很小的效能開銷,但程式退出時會慢很多,因為程式退出時會發生洩漏偵測。

記憶體 Sanitizer(MSAN)

記憶體清理程式是 doc_using_sanitizers_address_sanitizer 的補充。與位址清理程式不同,記憶體清理程式可以偵測未初始化的記憶體讀取。

若要在 Godot 建置中啟用記憶體清理程式,請在編譯時傳遞「use_msan=yes」SCons 選項。啟用 MSAN 通常會使產生的二進位檔案變慢約 3 倍。

警告

由於“設計決策<https://stackoverflow.com/questions/36971902/why-cant-clang-enable-all-sanitizers/>”,位址、記憶體和執行緒清理器是互斥的。這意味著您只能在給定的二進位檔案中使用其中一種消毒劑。

執行緒 Sanitizer(TSAN)

執行緒清理程式用於追蹤與多執行緒相關的競爭條件。競爭條件是指多個執行緒嘗試同時修改相同的資料。由於作業系統可以以任何方式對執行緒調度進行排序,因此這會導致偶爾發生的不正確行為(並且因此可能難以追蹤)。為了防止競爭條件,您需要新增一把鎖以確保在給定時間只有一個執行緒可以存取共享資料。

若要在 Godot 建置中啟用執行緒清理程式,請在編譯時傳遞“use_tsan=yes”SCons 選項。啟用 TSAN 通常會使產生的二進位檔案變慢 10 倍,同時也會使記憶體使用量增加約 8 倍。

警告

由於“設計決策<https://stackoverflow.com/questions/36971902/why-cant-clang-enable-all-sanitizers/>”,位址、記憶體和執行緒清理器是互斥的。這意味著您只能在給定的二進位檔案中使用其中一種消毒劑。

未定義行為 Sanitizer(UBSAN)

未定義行為清理器用於追蹤程式表現出隨機和不可預測行為的情況。這是因為 C/C++ 程式碼被編譯器接受,但不*正確*。使用不同的最佳化集進行編譯還可以更改未定義行為的觀察結果。

若要在 Godot 建置中啟用未定義行為清理程式,請在編譯時傳遞“use_ubsan=yes”SCons 選項。啟用 UBSAN 僅產生很小的效能開銷。

個別平台

Web

當為 Web 編譯 <doc_compiling_for_web>` 時,有 2 個額外的 sanitizer SCons 選項可用:

  • use_assertions=yes 啟用運作時 Emscripten 判斷提示,它可以捕獲各種問題。

  • use_safe_heap=yes 啟用 Emscripten 的 SAFE_HEAP 清理器。它提供與 ASAN 類似的功能,但它側重於 WebAssembly 特有的問題。 SAFE_HEAP 不保證與相同二進位檔案中的 ASAN 和 UBSAN 相容,因此您可能需要單獨建置它。