Runtime AddressSanitizer
Pustaka runtime AddressSanitizer mencegat fungsi dan operasi alokasi memori umum untuk memungkinkan inspeksi akses memori. Ada beberapa pustaka runtime berbeda yang mendukung berbagai jenis executable yang dapat dihasilkan pengkompilasi. Pengkompilasi dan linker secara otomatis menautkan pustaka runtime yang sesuai, selama Anda meneruskan opsi pada /fsanitize=address
waktu kompilasi. Anda dapat mengambil alih perilaku default dengan menggunakan opsi pada /NODEFAULTLIB
waktu tautan. Untuk informasi selengkapnya, lihat bagian tentang penautan dalam bahasa AddressSanitizer, build, dan referensi penelusuran kesalahan.
Saat mengkompilasi dengan cl /fsanitize=address
, pengkompilasi menghasilkan instruksi untuk mengelola dan memeriksa byte bayangan. Program Anda menggunakan instrumentasi ini untuk memeriksa akses memori pada tumpukan, dalam tumpukan, atau dalam cakupan global. Pengkompilasi juga menghasilkan metadata yang menjelaskan tumpukan dan variabel global. Metadata ini memungkinkan runtime untuk menghasilkan diagnostik kesalahan yang tepat: nama fungsi, baris, dan kolom dalam kode sumber Anda. Dikompilasi, pemeriksaan kompilator dan pustaka runtime dapat dengan tepat mendiagnosis banyak jenis bug keamanan memori jika ditemui pada run-time.
Daftar pustaka runtime untuk menautkan ke runtime AddressSanitizer, pada Visual Studio 17.7 Pratinjau 3, berikut. Untuk informasi selengkapnya tentang /MT
opsi (secara statis menautkan runtime) dan /MD
(secara dinamis menautkan redist saat runtime), lihat opsi /MD, /MT, /LD (Gunakan Pustaka Run-Time).
Catatan
Dalam tabel berikut, {arch}
adalah i386
atau x86_64
.
Pustaka ini menggunakan konvensi Clang untuk nama arsitektur. Konvensi MSVC biasanya x86
dan bukan i386
dan x64
x86_64
, tetapi mengacu pada arsitektur yang sama.
Opsi CRT | Pustaka runtime AddressSanitizer (.lib) | Biner runtime alamat (.dll) |
---|---|---|
/MT atau /MTd |
clang_rt.asan_dynamic-{arch} , clang_rt.asan_static_runtime_thunk-{arch} |
clang_rt.asan_dynamic-{arch} |
/MD atau /MDd |
clang_rt.asan_dynamic-{arch} , clang_rt.asan_dynamic_runtime_thunk-{arch} |
clang_rt.asan_dynamic-{arch} |
Diagram berikut menunjukkan bagaimana pustaka runtime bahasa ditautkan untuk /MT
opsi , , /MTd
/MD
, dan /MDd
pengkompilasi:
Gambar menunjukkan tiga skenario untuk menautkan pustaka runtime. Yang pertama adalah /MT atau /MTd. My_exe.exe dan my_dll.dll keduanya ditampilkan dengan salinan VCRuntime yang ditautkan secara statis, Universal CRT, dan runtime C++. Skenario menunjukkan /MD di mana my_exe.exe dan my_dll.dll berbagi vcruntime140.dll, ucrtbase.dll, dan msvcp140.dll. Skenario terakhir menunjukkan /MDd di mana my_exe.exe dan my_dll.dll berbagi versi debug runtime: vcruntime140d.dll, ucrtbased.dll, dan msvcp140d.dll
Diagram berikut menunjukkan bagaimana pustaka ASan ditautkan untuk berbagai opsi pengkompilasi:
Gambar menunjukkan empat skenario untuk menautkan pustaka runtime ASan. Skenarionya adalah untuk /MT (secara statis menautkan runtime), /MTd (secara statis menautkan runtime debug), /MD (secara dinamis menautkan redist pada runtime), /MDd (secara dinamis menautkan redist debug saat runtime). Dalam semua kasus, my_exe.exe tautan dan rekannya my_dll.dll tautan ke satu instans clang-rt.asan-dynamix-x86_64.dll.
Bahkan ketika menautkan secara statis, DLL runtime ASan harus ada pada runtime--tidak seperti komponen C Runtime lainnya.
Versi sebelumnya
Sebelum Visual Studio 17.7 Pratinjau 3, build yang ditautkan secara statis (/MT
atau /MTd
) tidak menggunakan dependensi DLL. Sebagai gantinya, runtime AddressSanitizer secara statis ditautkan ke EXE pengguna. Proyek DLL kemudian akan memuat ekspor dari EXE pengguna untuk mengakses fungsionalitas ASan.
Proyek yang ditautkan secara dinamis (/MD
atau /MDd
) menggunakan pustaka dan DLL yang berbeda tergantung pada apakah proyek dikonfigurasi untuk debug atau rilis. Untuk informasi selengkapnya tentang perubahan ini dan motivasinya, lihat MSVC Address Sanitizer – One DLL untuk semua Konfigurasi Runtime.
Tabel berikut ini menjelaskan perilaku sebelumnya dari penautan pustaka runtime AddressSanitizer, sebelum Pratinjau Visual Studio 17.7 3:
Opsi CRT | DLL atau EXE | DEBUG? | Pustaka ASan (.lib ) |
Biner runtime ASan (.dll ) |
---|---|---|---|---|
/MT |
EXE | No | clang_rt.asan-{arch} , clang_rt.asan_cxx-{arch} |
Tidak |
/MT |
DLL | No | clang_rt.asan_dll_thunk-{arch} |
Tidak |
/MD |
Baik | No | clang_rt.asan_dynamic-{arch} , clang_rt.asan_dynamic_runtime_thunk-{arch} |
clang_rt.asan_dynamic-{arch} |
/MT |
EXE | Ya | clang_rt.asan_dbg-{arch} , clang_rt.asan_dbg_cxx-{arch} |
Tidak |
/MT |
DLL | Ya | clang_rt.asan_dbg_dll_thunk-{arch} |
Tidak |
/MD |
Baik | Ya | clang_rt.asan_dbg_dynamic-{arch} , clang_rt.asan_dbg_dynamic_runtime_thunk-{arch} |
clang_rt.asan_dbg_dynamic-{arch} |
Diagram berikut menunjukkan bagaimana pustaka ASan ditautkan untuk berbagai opsi pengkompilasi sebelum Visual Studio 2022 17.7 Pratinjau 3:
Gambar menunjukkan empat skenario untuk menautkan pustaka runtime ASan. Skenarionya adalah untuk /MT (secara statis menautkan runtime), /MTd (secara statis menautkan runtime debug), /MD (secara dinamis menautkan redist pada runtime), /MDd (secara dinamis menautkan redist debug saat runtime). Untuk /MT, my_exe.exe memiliki salinan runtime ASan yang ditautkan secara statis. my_dll.dll tautan ke runtime ASan di my_exe.exe. Untuk /MTd, diagramnya sama kecuali menggunakan runtime ASan yang ditautkan secara statis debug. Untuk /MD, baik tautan my_exe.exe dan my_dll.dll ke runtime ASan yang ditautkan secara dinamis bernama clang_rt.asan_dynamic-x86_64.dll. Untuk /MDd, diagramnya sama kecuali tautan my_exe.exe dan my_dll.dll ke runtime ASan debug bernama clang_rt.asan_dbg_dynamic-x86_64.dll.
Intersepsi fungsi
AddressSanitizer mencapai intersepsi fungsi melalui banyak teknik hotpatching. Teknik ini paling baik didokumenkan dalam kode sumber itu sendiri.
Pustaka runtime mencegat banyak manajemen memori umum dan fungsi manipulasi memori. Untuk daftar, lihat Daftar AddressSanitizer fungsi yang disadap. Pencegat alokasi mengelola metadata dan byte bayangan yang terkait dengan setiap panggilan alokasi. Setiap kali fungsi CRT seperti malloc
atau delete
dipanggil, pencegat menetapkan nilai tertentu di wilayah memori bayangan AddressSanitizer untuk menunjukkan apakah lokasi timbunan tersebut saat ini dapat diakses dan apa batas alokasinya. Byte bayangan ini memungkinkan pemeriksaan byte bayangan yang dihasilkan kompilator untuk menentukan apakah beban atau penyimpanan valid.
Intersepsi tidak dijamin berhasil. Jika prolog fungsi terlalu singkat untuk jmp
ditulis, penyadapan dapat gagal. Jika kegagalan intersepsi terjadi, program akan melempar debugbreak
dan menghentikan. Jika Anda melampirkan debugger, itu membuat penyebab masalah intersepsi menjadi jelas. Jika Anda memiliki masalah ini, laporkan bug.
Catatan
Pengguna dapat secara opsional mencoba untuk melanjutkan melewati intersepsi yang gagal dengan mengatur variabel ASAN_WIN_CONTINUE_ON_INTERCEPTION_FAILURE
lingkungan ke nilai apa pun. Melanjutkan melewati kegagalan intersepsi dapat mengakibatkan laporan bug yang terlewat untuk fungsi tersebut.
Alokator kustom dan runtime AddressSanitizer
Runtime AddressSanitizer menyediakan pencegat untuk antarmuka alokator umum, , malloc
/free
, new
delete
HeapFree
HeapAlloc
//(melalui ).RtlAllocateHeap
/RtlFreeHeap
Banyak program menggunakan alokator kustom karena satu alasan atau lainnya, contohnya adalah program apa pun yang menggunakan dlmalloc
atau solusi menggunakan std::allocator
antarmuka dan VirtualAlloc()
. Pengkompilasi tidak dapat secara otomatis menambahkan panggilan manajemen memori bayangan ke alokator kustom. Pengguna bertanggung jawab untuk menggunakan antarmuka keracunan manual yang disediakan. API ini memungkinkan alokator ini berfungsi dengan baik dengan runtime AddressSanitizer yang ada dan konvensi byte bayangan.
Antarmuka keracunan AddressSanitizer Manual
Antarmuka untuk pencerahan sederhana, tetapi memberlakukan pembatasan penyelarasan pada pengguna. Pengguna dapat mengimpor prototipe ini dengan mengimpor sanitizer/asan_interface.h
. Berikut adalah prototipe fungsi antarmuka:
void __asan_poison_memory_region(void const volatile *addr, size_t size);
void __asan_unpoison_memory_region(void const volatile *addr, size_t size);
Untuk kenyamanan, file header antarmuka AddressSanitizer menyediakan makro pembungkus. Makro ini memeriksa apakah fungsionalitas AddressSanitizer diaktifkan selama kompilasi. Mereka memungkinkan kode sumber Anda untuk menghilangkan panggilan fungsi keracunan saat tidak diperlukan. Makro ini harus lebih disukai daripada memanggil fungsi di atas secara langsung:
#define ASAN_POISON_MEMORY_REGION(addr, size)
#define ASAN_UNPOISON_MEMORY_REGION(addr, size)
Persyaratan penyelarasan untuk keracunan AddressSanitizer
Setiap keracunan manual byte bayangan harus mempertimbangkan persyaratan penyelarasan. Pengguna harus menambahkan padding jika perlu sehingga byte bayangan berakhir pada batas byte dalam memori bayangan. Setiap bit dalam memori bayangan AddressSanitizer mengodekan status byte tunggal dalam memori aplikasi. Pengodean ini berarti ukuran total setiap alokasi, termasuk padding apa pun, harus selaras dengan batas 8 byte. Jika persyaratan penyelarasan tidak terpenuhi, persyaratan tersebut dapat menyebabkan pelaporan bug yang salah. Pelaporan yang salah dapat bermanifestasi sebagai laporan yang hilang (negatif palsu) atau laporan tentang non-kesalahan (positif palsu).
Untuk ilustrasi persyaratan perataan dan potensi masalah, lihat contoh perataan ASan yang disediakan. Salah satunya adalah program kecil untuk menunjukkan apa yang bisa salah dengan keracunan memori bayangan manual. Yang kedua adalah contoh implementasi keracunan manual menggunakan std::allocator
antarmuka.
Opsi run-time
Microsoft C/C++ (MSVC) menggunakan runtime berdasarkan runtime Clang AddressSanitizer dari repositori llvm-project. Karena itu, sebagian besar opsi runtime dibagikan antara dua versi. Daftar lengkap opsi runtime Clang publik tersedia di sini. Kami mendokumen beberapa perbedaan di bagian berikut. Jika Anda menemukan opsi yang tidak berfungsi seperti yang diharapkan, laporkan bug.
Opsi AddressSanitizer yang tidak didukung
- detect_container_overflow
- unmap_shadow_on_exit
Catatan
Opsi halt_on_error
runtime AddressSanitizer tidak berfungsi seperti yang mungkin Anda harapkan. Dalam pustaka runtime Clang dan MSVC, banyak jenis kesalahan dianggap tidak dapat dilanjutkan, termasuk sebagian besar kesalahan kerusakan memori.
Untuk informasi selengkapnya, lihat bagian Perbedaan dengan Clang 12.0 .
Opsi runtime AddressSanitizer khusus MSVC
windows_hook_legacy_allocators
Boolean, atur kefalse
untuk menonaktifkan intersepsiGlobalAlloc
danLocalAlloc
alokator.Catatan
Opsi
windows_hook_legacy_allocators
ini tidak tersedia di runtime proyek llvm publik saat artikel ini ditulis. Opsi pada akhirnya dapat dikontribusikan kembali ke proyek publik; namun, itu tergantung pada tinjauan kode dan penerimaan komunitas.Opsi
windows_hook_rtl_allocators
, sebelumnya fitur keikutsertaan saat AddressSanitizer bersifat eksperimental, sekarang diaktifkan secara default. Dalam versi sebelum Visual Studio 2022 versi 17.4.6, nilai opsi defaultnya adalahfalse
. Di Visual Studio 2022 versi 17.4.6 dan versi yang lebih baru, opsiwindows_hook_rtl_allocators
default ketrue
.iat_overwrite
String, diatur ke"error"
secara default. Nilai lain yang mungkin adalah"protect"
dan"ignore"
. Beberapa modul dapat menimpaimport address table
modul lain untuk menyesuaikan implementasi fungsi tertentu. Misalnya, driver biasanya menyediakan implementasi kustom untuk perangkat keras tertentu. Opsiiat_overwrite
mengelola perlindungan runtime AddressSanitizer terhadap penimpaan untuk fungsi tertentumemoryapi.h
. Runtime saat ini melacakVirtualAlloc
fungsi ,VirtualProtect
, danVirtualQuery
untuk perlindungan. Opsi ini tersedia di Visual Studio 2022 versi 17.5 Pratinjau 1 dan versi yang lebih baru. Nilai berikutiat_overwrite
mengontrol bagaimana runtime bereaksi saat fungsi yang dilindungi ditimpa:- Jika diatur ke
"error"
(default), runtime melaporkan kesalahan setiap kali penimpaan terdeteksi. - Jika diatur ke
"protect"
, runtime mencoba menghindari penggunaan definisi yang ditimpa dan melanjutkan. Secara efektif, definisi aslimemoryapi
fungsi digunakan dari dalam runtime untuk menghindari rekursi tak terbatas. Modul lain dalam proses masih menggunakan definisi yang ditimpa. - Jika diatur ke
"ignore"
, runtime tidak mencoba memperbaiki fungsi yang ditimpa dan melanjutkan eksekusi.
- Jika diatur ke
windows_fast_fail_on_error
Boolean (false secara default), atur ketrue
untuk mengaktifkan proses untuk mengakhiri dengan __fastfail(71) setelah mencetak laporan kesalahan.
Catatan
Ketika nilai abort_on_error diatur ke true, pada Windows program berakhir dengan exit(3). Agar tidak mengubah perilaku saat ini, kami memutuskan untuk memperkenalkan opsi baru ini sebagai gantinya. Jika abort_on_error dan windows_fast_fail_on_error benar, program akan keluar dengan __fastfail.
Daftar AddressSanitizer dari fungsi yang dicegat (Windows)
Runtime AddressSanitizer melakukan hotpatch pada banyak fungsi untuk mengaktifkan pemeriksaan keamanan memori pada runtime. Berikut adalah daftar fungsi yang tidak lengkap yang dipantau runtime AddressSanitizer.
Pencegat default
__C_specific_handler
(hanya x64)_aligned_free
_aligned_malloc
_aligned_msize
_aligned_realloc
_calloc_base
_calloc_crt
_calloc_dbg
(hanya runtime debug)_except_handler3
(hanya x86)_except_handler4
(hanya x86) (tidak terdokumentasi)_expand
_expand_base
(tidak terdokumentasi)_expand_dbg
(hanya runtime debug)_free_base
(tidak terdokumentasi)_free_dbg
(hanya runtime debug)_malloc_base
(tidak terdokumentasi)_malloc_crt
(tidak terdokumentasi)_malloc_dbg
(hanya runtime debug)_msize
_msize_base
(tidak terdokumentasi)_msize_dbg
(hanya runtime debug)_realloc_base
(tidak terdokumentasi)_realloc_crt
(tidak terdokumentasi)_realloc_dbg
(hanya runtime debug)_recalloc
_recalloc_base
(tidak terdokumentasi)_recalloc_crt
(tidak terdokumentasi)_recalloc_dbg
(hanya runtime debug)_strdup
atoi
atol
calloc
CreateThread
free
frexp
longjmp
malloc
memchr
memcmp
memcpy
memmove
memset
RaiseException
realloc
RtlAllocateHeap
RtlCreateHeap
RtlDestroyHeap
RtlFreeHeap
RtlRaiseException
RtlReAllocateHeap
(tidak terdokumentasi)RtlSizeHeap
(tidak terdokumentasi)SetUnhandledExceptionFilter
strcat
strchr
strcmp
strcpy
strcspn
strdup
strlen
strncat
strncmp
strncpy
strnlen
strpbrk
strspn
strstr
strtok
strtol
wcslen
wcsnlen
Pencegat opsional
Pencegat yang tercantum di sini hanya diinstal ketika opsi runtime AddressSanitizer diaktifkan. Atur windows_hook_legacy_allocators
ke false
untuk menonaktifkan intersepsi alokator warisan.
set ASAN_OPTIONS=windows_hook_legacy_allocators=false
GlobalAlloc
GlobalFree
GlobalHandle
GlobalLock
GlobalReAlloc
GlobalSize
GlobalUnlock
LocalAlloc
LocalFree
LocalHandle
LocalLock
LocalReAlloc
LocalSize
LocalUnlock
Lihat juga
Gambaran umum AddressSanitizer
Masalah yang diketahui AddressSanitizer
Referensi bahasa dan build AddressSanitizer
Byte bayangan AddressSanitizer
AddressSanitizer cloud atau pengujian terdistribusi
Integrasi debugger AddressSanitizer
Contoh kesalahan AddressSanitizer
Saran dan Komentar
https://aka.ms/ContentUserFeedback.
Segera hadir: Sepanjang tahun 2024 kami akan menghentikan penggunaan GitHub Issues sebagai mekanisme umpan balik untuk konten dan menggantinya dengan sistem umpan balik baru. Untuk mengetahui informasi selengkapnya, lihat:Kirim dan lihat umpan balik untuk