Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Библиотека среды выполнения AddressSanitizer перехватывает общие функции выделения памяти и операции, чтобы обеспечить проверку доступа к памяти. Существует несколько различных библиотек среды выполнения, поддерживающих различные типы исполняемых файлов компилятора. Компилятор и компоновщик автоматически связывают соответствующие библиотеки среды выполнения, если вы передаете /fsanitize=address параметр во время компиляции. Поведение по умолчанию можно переопределить с помощью /NODEFAULTLIB параметра во время ссылки. Дополнительные сведения см. в разделе о связывании на языке AddressSanitizer, сборке и отладке.
При компиляции с cl /fsanitize=addressпомощью компилятор создает инструкции по управлению и проверке теневых байтов. Программа использует эту инструментацию для проверки доступа к памяти в стеке, в куче или в глобальной области. Компилятор также создает метаданные, описывающие стек и глобальные переменные. Эти метаданные позволяют среде выполнения создавать точные диагностика ошибки: имена функций, строки и столбцы в исходном коде. В сочетании компилятор проверяет и библиотеки среды выполнения точно диагностировать многие типы ошибок безопасности памяти, если они обнаружены во время выполнения.
Список библиотек среды выполнения для связывания со средой выполнения AddressSanitizer по состоянию на Visual Studio 17.7( предварительная версия 3) следует. Дополнительные сведения о /MT параметрах (статически связывая среду выполнения) и /MD (динамически связывая редист в среде выполнения) см. в разделе /MD, /MT/LD (Использование библиотеки Run-Time).
Note
В следующей таблице имеет {arch} значение i386 или x86_64.
Эти библиотеки используют соглашения Clang для имен архитектуры. Соглашения MSVC обычно x86 и x64 не i386x86_64относятся к тем же архитектурам.
| Параметр CRT | Библиотека среды выполнения AddressSanitizer (.lib) |
Двоичный файл среды выполнения адресов (.dll) |
|---|---|---|
/MT или /MTd |
clang_rt.asan_dynamic-{arch}, clang_rt.asan_static_runtime_thunk-{arch} |
clang_rt.asan_dynamic-{arch} |
/MD или /MDd |
clang_rt.asan_dynamic-{arch}, clang_rt.asan_dynamic_runtime_thunk-{arch} |
clang_rt.asan_dynamic-{arch} |
На следующей схеме показано, как библиотеки языковой среды выполнения связаны для /MTпараметров компилятора , /MTdа /MD также для параметров компилятора/MDd:
На изображении показаны три сценария связывания библиотеки среды выполнения. Первый — /MT или /MTd. My_exe.exe и my_dll.dll отображаются с собственными копиями статически связанных сред выполнения VCRuntime, universal CRT и C++ . В сценариях показано значение /MD, в котором my_exe.exe и my_dll.dll совместно использовать vcruntime140.dll, ucrtbase.dll и msvcp140.dll. Последний сценарий показывает /MDd, в котором my_exe.exe и my_dll.dll совместно использовать отладочные версии сред выполнения: vcruntime140d.dll, ucrtbased.dll и msvcp140d.dll
На следующей схеме показано, как библиотека ASan связана для различных параметров компилятора:
На рисунке показаны четыре сценария связывания библиотеки среды выполнения ASan. Сценарии предназначены для /MT (статически связывающая среду выполнения), /MTd (статически связывающая среду выполнения отладки), /MD (динамически связывающая redist во время выполнения), /MDd (динамически связывает отладочный редист во время выполнения). Во всех случаях my_exe.exe ссылки и его связывания my_dll.dll ссылку на один экземпляр clang_rt.asan_dynamic-x86_64.dll.
Даже при статической компоновке библиотека DLL среды выполнения ASan должна присутствовать во время выполнения, в отличие от других компонентов среды выполнения C.
предыдущих версий
До Предварительной версии 3 Visual Studio 17.7 статически связанные сборки (/MT или /MTd) не использовали зависимость DLL. Вместо этого среда выполнения AddressSanitizer была статически связана с EXE пользователя. Затем проекты DLL загружают экспорт из EXE пользователя для доступа к функциям ASan.
Динамически связанные проекты (/MD или /MDd) использовали разные библиотеки и библиотеки DLL в зависимости от того, настроен ли проект для отладки или выпуска. Дополнительные сведения об этих изменениях и их мотивации см. в статье MSVC AddressSanitizer — одна библиотека DLL для всех конфигураций среды выполнения.
В следующей таблице описано предыдущее поведение связывания библиотеки среды выполнения AddressSanitizer до Visual Studio 17.7 Preview 3:
| Параметр CRT | DLL или EXE | DEBUG? | Библиотека ASan (.lib) |
Двоичный файл среды выполнения 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} |
На следующей схеме показано, как библиотека ASan была связана для различных параметров компилятора до Visual Studio 2022 17.7 Preview 3:
На рисунке показаны четыре сценария связывания библиотеки среды выполнения ASan. Сценарии предназначены для /MT (статически связывающая среду выполнения), /MTd (статически связывающая среду выполнения отладки), /MD (динамически связывающая redist во время выполнения), /MDd (динамически связывает отладочный редист во время выполнения). Для /MT my_exe.exe имеет статическую копию среды выполнения ASan. my_dll.dll ссылки на среду выполнения ASan в my_exe.exe. Для /MTd схема одинакова, за исключением того, что она использует отладочную статическую связанную среду выполнения ASan. Для /MD my_exe.exe и my_dll.dll ссылку на динамически связанную среду выполнения ASan с именем clang_rt.asan_dynamic-x86_64.dll. Для /MDd схема совпадает с my_exe.exe и my_dll.dll ссылкой на отладочную среду выполнения ASan с именем clang_rt.asan_dbg_dynamic-x86_64.dll.
Перехват функций
AddressSanitizer достигает перехвата функций с помощью многих методов горячей патчинга. Эти методы лучше всего документируются в самом исходном коде.
Библиотеки среды выполнения перехватывают множество распространенных функций управления памятью и операций с памятью. Список списков см. в списке "AddressSanitizer" для перехваченных функций. Перехватчики выделения управляют метаданными и теневыми байтами, связанными с каждым вызовом выделения. При каждом вызове функции CRT, например malloc или delete вызове, перехватчики задают определенные значения в регионе теневой памяти AddressSanitizer, чтобы указать, доступны ли эти кучи и какие границы выделения имеются. Эти теневые байты позволяют компилятору проверять теневые байты , чтобы определить, является ли загрузка или хранилище допустимым.
Перехват не гарантируется успешно. Если пролог функции слишком короткий для jmp записи, перехват может завершиться ошибкой. Если происходит сбой перехвата, программа выдает debugbreak и останавливается. Если подключить отладчик, это делает причину проблемы перехвата ясной. Если у вас эта проблема, сообщите об ошибке.
Note
Пользователи могут при необходимости попытаться продолжить перехват после сбоя, задав переменную ASAN_WIN_CONTINUE_ON_INTERCEPTION_FAILURE среды любому значению. Продолжение последнего сбоя перехвата может привести к пропущенным отчетам об ошибках для этой функции.
Пользовательские распределители и среда выполнения AddressSanitizer
Среда выполнения AddressSanitizer предоставляет перехватчики для общих интерфейсов распределителя, malloc/free, (new/deleteHeapAlloc/HeapFreeчерез).RtlAllocateHeap/RtlFreeHeap Многие программы используют пользовательские распределители по одной или другой причине, например, любой программой dlmalloc или решением с помощью std::allocator интерфейса и VirtualAlloc(). Компилятор не может автоматически добавлять вызовы управления теневой памятью в пользовательский распределитель. Это ответственность пользователя за использование предоставленного интерфейса ручного отравления. Этот API позволяет этим распределителям правильно работать с существующими соглашениями среды выполнения AddressSanitizer и теневых байтов .
Интерфейс отравлений AddressSanitizer вручную
Интерфейс для просвещений прост, но он накладывает ограничения выравнивания для пользователя. Пользователи могут импортировать эти прототипы путем импорта sanitizer/asan_interface.h. Ниже приведены прототипы функций интерфейса:
void __asan_poison_memory_region(void const volatile *addr, size_t size);
void __asan_unpoison_memory_region(void const volatile *addr, size_t size);
Для удобства файл заголовка интерфейса AddressSanitizer предоставляет макросы оболочки. Эти макросы проверяют, включена ли функция AddressSanitizer во время компиляции. Они позволяют исходному коду пропускать вызовы функции отравлений, если они не нужны. Эти макросы должны быть предпочтительнее при вызове указанных выше функций напрямую:
#define ASAN_POISON_MEMORY_REGION(addr, size)
#define ASAN_UNPOISON_MEMORY_REGION(addr, size)
Note
Если вы вручную отравляете память, перед повторной использованием его необходимо распулить. Это особенно важно для адресов стека, таких как для локальной переменной, которая часто используется во время выполнения программы. Вы рискуете вводить use-after-poison ложные срабатывания в адресах стека вручную, если вы не разложите их перед удалением кадра стека.
Требования к выравниванию для отравлений AddressSanitizer
Любое отравление теневых байтов вручную должно учитывать требования к выравниванию. Пользователь должен добавить заполнение при необходимости, чтобы теневые байты заканчивались на границе байтов в теневой памяти. Каждый бит в теневой памяти AddressSanitizer кодирует состояние одного байта в памяти приложения. Это кодировка означает общий размер каждого выделения, включая любую заполнение, должен выровняться по 8-байтовой границе. Если требование выравнивания не удовлетворено, это может привести к неправильному отчету об ошибках. Неправильные отчеты могут проявляться как отсутствующие отчеты (ложные отрицательные) или отчеты о неисправных ошибках (ложные срабатывания).
Иллюстрация требования выравнивания и потенциальных проблем см. в приведенных примерах выравнивания ASan. Одна из них небольшая программа, чтобы показать, что может пойти не так с отравлением теневой памяти вручную. Второй пример реализации ручного отравления с помощью std::allocator интерфейса.
Параметры среды выполнения
MSVC AddressSanitizer — это регулярно синхронизированный вилок среды выполнения Clang AddressSanitizer. В результате MSVC неявно наследует многие параметры среды выполнения ASan в Clang. Полный список параметров, которые мы активно поддерживаем и тестируем, можно найти здесь. Если вы обнаружите параметры, которые не работают должным образом, сообщите об ошибке.
Настройка параметров среды выполнения
Параметры среды выполнения ASan задаются одним из двух способов:
- Переменная среды
ASAN_OPTIONS - Пользовательская
__asan_default_optionsфункция
Если переменная среды и пользовательская функция указывают конфликтующие параметры, то параметры в ASAN_OPTIONS переменной среды имеют приоритет.
Несколько параметров задаются путем разделения их двоеточием (:).
В следующем примере задано alloc_dealloc_mismatch значение 1 и symbolize равно нулю:
set ASAN_OPTIONS=alloc_dealloc_mismatch=1:symbolize=0
Или добавьте в код следующую функцию:
extern "C" const char* __asan_default_options()
{
return "alloc_dealloc_mismatch=1:symbolize=0";
}
Неподдерживаемые параметры AddressSanitizer
detect_container_overflowunmap_shadow_on_exit
Note
Параметр halt_on_error среды выполнения AddressSanitizer не работает так, как можно ожидать. В библиотеках среды выполнения Clang и MSVC многие типы ошибок считаются неконтинуируемыми, включая большинство ошибок повреждения памяти.
Дополнительные сведения см. в разделе "Различия с Clang 12.0 ".
Параметры среды выполнения AddressSanitizer для MSVC
continue_on_errorЛогическое значение, заданноеfalseпо умолчанию. Если задано значениеtrue, программа позволяет программе продолжать выполняться после сообщения о нарушении памяти, что позволяет собирать несколько отчетов об ошибках.iat_overwriteСтрока, заданная"error"по умолчанию. Существуют и другие возможные"protect""ignore"значения. Некоторые модули могут перезаписатьimport address tableдругие модули для настройки реализаций определенных функций. Например, драйверы обычно предоставляют пользовательские реализации для конкретного оборудования. Параметрiat_overwriteуправляет защитой среды выполнения AddressSanitizer от перезаписей для определенныхmemoryapi.hфункций. Среда выполнения в настоящее время отслеживаетVirtualAllocиVirtualProtectVirtualQueryфункции для защиты. Этот параметр доступен в Visual Studio 2022 версии 17.5( предварительная версия 1 и более поздние версии). Следующиеiat_overwriteзначения определяют, как среда выполнения реагирует при перезаписи защищенных функций:- Если задано значение
"error"(по умолчанию), среда выполнения сообщает об ошибке при обнаружении перезаписи. - Если задано значение
"protect", среда выполнения пытается избежать использования перезаписываемого определения и продолжается. Фактически исходноеmemoryapiопределение функции используется внутри среды выполнения, чтобы избежать бесконечного рекурсии. Другие модули в процессе по-прежнему используют перезаписанный определение. - Если задано значение
"ignore", среда выполнения не пытается исправить перезаписанные функции и продолжает выполнение.
- Если задано значение
windows_fast_fail_on_errorЛогическое значение (falseпо умолчанию), установите дляtrueвключения процесса завершения работы с__fastfail(71)отчетом об ошибке после печати отчета об ошибке.Note
Если
abort_on_errorзаданоtrueзначение , в Windows программа завершается с параметромexit(3). Чтобы не изменить текущее поведение, мы решили вместо этого ввести этот новый параметр. Если обаabort_on_errorиwindows_fast_fail_on_errorестьtrue, программа завершит работу с__fastfail.windows_hook_legacy_allocatorsЛогический, установите дляfalseотключения перехватаGlobalAllocиLocalAllocраспределителей.Note
windows_hook_legacy_allocatorsПараметр недоступен в общедоступной среде выполнения llvm-project при написании этой статьи. Этот вариант в конечном итоге может быть добавлен в общедоступный проект; однако это зависит от проверки кода и принятия сообщества.windows_hook_rtl_allocatorsПараметр , ранее вариант согласия, в то время как AddressSanitizer был экспериментальным, теперь включен по умолчанию. В версиях до Visual Studio 2022 версии 17.4.6 значение параметра по умолчанию равноfalse. В Visual Studio 2022 версии 17.4.6 и более поздних версиях параметрwindows_hook_rtl_allocatorsпоtrueумолчанию.
Список перехваченных функций AddressSanitizer (Windows)
Среда выполнения AddressSanitizer позволяет выполнять многие функции, чтобы обеспечить проверку безопасности памяти во время выполнения. Ниже приведен полный список функций, отслеживаемых средой выполнения AddressSanitizer.
Перехватчики по умолчанию
-
__C_specific_handler(только x64) _aligned_free_aligned_malloc_aligned_msize_aligned_realloc_calloc_base_calloc_crt-
_calloc_dbg(только для среды выполнения отладки) -
_except_handler3(только x86) -
_except_handler4(только x86) (undocumented) _expand-
_expand_base(undocumented) -
_expand_dbg(только для среды выполнения отладки) -
_free_base(undocumented) -
_free_dbg(только для среды выполнения отладки) -
_malloc_base(undocumented) -
_malloc_crt(undocumented) -
_malloc_dbg(только для среды выполнения отладки) _msize-
_msize_base(undocumented) -
_msize_dbg(только для среды выполнения отладки) -
_realloc_base(undocumented) -
_realloc_crt(undocumented) -
_realloc_dbg(только для среды выполнения отладки) _recalloc-
_recalloc_base(undocumented) -
_recalloc_crt(undocumented) -
_recalloc_dbg(только для среды выполнения отладки) _strdupatoiatolcallocCreateThreadfreefrexplongjmpmallocmemchrmemcmpmemcpymemmovememsetRaiseExceptionreallocRtlAllocateHeapRtlCreateHeapRtlDestroyHeapRtlFreeHeapRtlRaiseException-
RtlReAllocateHeap(undocumented) -
RtlSizeHeap(undocumented) SetUnhandledExceptionFilterstrcatstrchrstrcmpstrcpystrcspnstrdupstrlenstrncatstrncmpstrncpystrnlenstrpbrkstrspnstrstrstrtokstrtolwcslenwcsnlen
Необязательные перехватчики
Перехватчики, перечисленные здесь, устанавливаются только в том случае, если включен параметр среды выполнения AddressSanitizer. Установите для windows_hook_legacy_allocatorsfalse отключения перехвата устаревшего распределителя.
set ASAN_OPTIONS=windows_hook_legacy_allocators=false
GlobalAllocGlobalFreeGlobalHandleGlobalLockGlobalReAllocGlobalSizeGlobalUnlockLocalAllocLocalFreeLocalHandleLocalLockLocalReAllocLocalSizeLocalUnlock
См. также
Обзор AddressSanitizer
Известные проблемы AddressSanitizer
Справочник по сборке и языку AddressSanitizer
Теневой байт AddressSanitizer
Облачное или распределенное тестирование AddressSanitizer
Интеграция отладчика AddressSanitizer
Примеры ошибок AddressSanitizer