Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
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. For more information, see the section on linking in the AddressSanitizer language, build, and debugging reference.
When compiling with cl /fsanitize=address
, the compiler generates instructions to manage and check shadow bytes. 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).
Note
Dalam tabel berikut, {arch}
adalah i386
atau x86_64
.
Pustaka ini menggunakan konvensi Clang untuk nama arsitektur. Konvensi MSVC biasanya x86
dan bukan x64
dan i386
x86_64
, tetapi mengacu pada arsitektur yang sama.
CRT option | 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.
Previous versions
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:
CRT option | DLL atau EXE | DEBUG? | Pustaka ASan (.lib ) |
Biner runtime ASan (.dll ) |
---|---|---|---|---|
/MT |
EXE | No |
clang_rt.asan-{arch} , clang_rt.asan_cxx-{arch} |
None |
/MT |
DLL | No | clang_rt.asan_dll_thunk-{arch} |
None |
/MD |
Either | No |
clang_rt.asan_dynamic-{arch} , clang_rt.asan_dynamic_runtime_thunk-{arch} |
clang_rt.asan_dynamic-{arch} |
/MT |
EXE | Yes |
clang_rt.asan_dbg-{arch} , clang_rt.asan_dbg_cxx-{arch} |
None |
/MT |
DLL | Yes | clang_rt.asan_dbg_dll_thunk-{arch} |
None |
/MD |
Either | Yes |
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.
Function interception
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. These shadow bytes allow the compiler-generated checks of the shadow bytes to determine whether a load or store is 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.
Note
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
HeapAlloc
/HeapFree
(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. This API enables these allocators to function properly with the existing AddressSanitizer runtime and shadow byte conventions.
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)
Note
Jika Anda meracuni memori secara manual, Anda harus membukanya sebelum digunakan kembali. Ini sangat penting untuk alamat tumpukan, seperti untuk variabel lokal, yang sering digunakan kembali selama eksekusi program. Anda berisiko memperkenalkan use-after-poison
positif palsu dalam alamat tumpukan yang diracuni secara manual jika Anda tidak melepasnya sebelum bingkai tumpukannya dihapus.
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.
Runtime options
MSVC AddressSanitizer didasarkan pada runtime Clang AddressSanitizer dari repositori llvm-project. Karena itu, sebagian besar opsi runtime bahasa umum ASan clang juga tersedia di MSVC. 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.
Mengonfigurasi opsi runtime
Opsi runtime ASan diatur dalam salah satu dari dua cara:
- Variabel
ASAN_OPTIONS
lingkungan - Fungsi
__asan_default_options
pengguna
Jika variabel lingkungan dan fungsi pengguna menentukan opsi yang bertentangan, opsi dalam ASAN_OPTIONS
variabel lingkungan diutamakan.
Beberapa opsi ditentukan dengan memisahkannya dengan titik dua (:
).
Contoh berikut diatur alloc_dealloc_mismatch
ke satu dan symbolize
ke nol:
set ASAN_OPTIONS=alloc_dealloc_mismatch=1:symbolize=0
Atau tambahkan fungsi berikut ke kode Anda:
extern "C" const char* __asan_default_options()
{
return "alloc_dealloc_mismatch=1:symbolize=0";
}
Opsi AddressSanitizer yang tidak didukung
- detect_container_overflow
- unmap_shadow_on_exit
Note
Opsi halt_on_error
runtime AddressSanitizer tidak berfungsi seperti yang mungkin Anda harapkan. In both the Clang and the MSVC runtime libraries, many error types are considered non-continuable, including most memory corruption errors.
Untuk informasi selengkapnya, lihat bagian Perbedaan dengan Clang 12.0 .
Opsi runtime AddressSanitizer khusus MSVC
continue_on_error
Boolean, atur kefalse
secara default. Ketika diatur ketrue
, ini memungkinkan program untuk terus mengeksekusi setelah pelanggaran memori dilaporkan, memungkinkan Anda untuk mengumpulkan beberapa laporan kesalahan.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.
Note
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.
windows_hook_legacy_allocators
Boolean, atur kefalse
untuk menonaktifkan intersepsiGlobalAlloc
danLocalAlloc
alokator.Note
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
.
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.
Default interceptors
-
__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
Optional interceptors
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
See also
AddressSanitizer overview
Masalah yang diketahui AddressSanitizer
Referensi bahasa dan build AddressSanitizer
Byte bayangan AddressSanitizer
AddressSanitizer cloud atau pengujian terdistribusi
Integrasi debugger AddressSanitizer
Contoh kesalahan AddressSanitizer