在 Visual Studio 2022 打開 AddressSanitizer (CMake+MSVC)

前言

AddressSanitizer (ASAN) 是記憶體除錯利器,除了 MSVC 實做的,比較知名的元老是 Google 實做的版本

面對一些比較基礎的記憶體問題如 buffer overflow,許多 IDE 內建的掃描即可在編輯器中提示。但面對 runtime 較為複雜如 race condition 時候才會出現的記憶體問題,就有賴 Sanitizer 動態跟蹤除錯了。

筆者最近遇到程式結束時 double free 問題,從 debugger 的 parallel stacks 只看得出來是系統在清理時遭遇到,看不出來是哪個物件,在這種情境下就很適合用 Sanitizer 來協助告知究竟是哪一行程式碼出問題。

支援的記憶體問題

微軟官方文件提到 VS 2019 (16.9) 後開始支援 Sanitizer,可以找出記憶體錯誤的種類包含:

  • Alloc/dealloc mismatches and new/delete type mismatches
  • Allocations too large for the heap
  • calloc overflow and alloca overflow
  • Double free and use after free
  • Global variable overflow
  • Heap buffer overflow
  • Invalid alignment of aligned values
  • memcpy and strncat parameter overlap
  • Stack buffer overflow and underflow
  • Stack use after return and use after scope
  • Memory use after it’s poisoned

設定

雖然微軟文件說 CMake 專案只需要設定 "addressSanitizerEnabled": true **,**但實際上這麼做並無法成功。

不管是用 MSVC 或是 clang,都必須要告知 compiler 與 linker 要使用 AddressSanitizer。因此在 CMake 加上:

add_compile_options(-fsanitize=address)
add_compile_options(-fno-omit-frame-pointer)
add_link_options(-fsanitize=address)
add_link_options(-fno-omit-frame-pointer)

通常來說這樣就夠了,但是直接執行的話,會遇到

這是因為該 DLL 沒有被放進 System32,因此在動態連結會出問題。

緩解方式是到 C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.35.32215\bin\Hostx64\x64clang_rt.asan_dbg_dynamic-x86_64.dll 複製一份到 MSVC 的 build folder 即可。

當然,不想手動複製的話,可以用 CMake install 方式:

install(FILES "C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.35.32215/bin/Hostx64/x64/clang_rt.asan_dbg_dynamic-x86_64.dll" DESTINATION ${CMAKE_BINARY_DIR})

重新執行就可以看到成功抓到 bof。

備註

在 Sanitizer 整合性上面,CLion 做得比 Visual Studio 還要好,有獨立的視窗顯示跟蹤結果,JetBrains 不愧是專業 IDE 開發公司。

Untitled

參考

  1. What’s the proper way to enable AddressSanitizer in CMake that works in Xcode
  2. Application crashes when using address sanitizer with MSVC

comments powered by Disqus