Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
A biblioteca de runtime do AddressSanitizer intercepta funções e operações comuns de alocação de memória para habilitar a inspeção de acessos de memória. Há várias bibliotecas de runtime diferentes que dão suporte aos vários tipos de executáveis que o compilador pode gerar. O compilador e o vinculador associam automaticamente as bibliotecas de runtime apropriadas, desde que você passe a opção /fsanitize=address no tempo de compilação. Você pode substituir o comportamento padrão usando a opção no momento da /NODEFAULTLIB vinculação. Para obter mais informações, consulte a seção sobre como vincular a linguagem AddressSanitizer, a compilação e a referência de depuração.
Ao compilar com cl /fsanitize=address, o compilador gera instruções para gerenciar e verificar bytes de sombra. Seu programa usa essa instrumentação para verificar os acessos de memória na pilha, no heap ou no escopo global. O compilador também produz metadados que descrevem variáveis globais e de pilha. Esses metadados permitem que o runtime gere um diagnóstico de erro preciso: nomes de função, linhas e colunas no código-fonte. Combinadas, as verificações do compilador e as bibliotecas de runtime podem diagnosticar precisamente muitos tipos de bugs de segurança de memória se forem encontrados em tempo de execução.
A lista de bibliotecas de runtime para vincular ao runtime AddressSanitizer, a partir do Visual Studio 17.7 Preview 3, a seguir. Para obter mais informações sobre as /MT opções (vincular estaticamente o runtime) e /MD (vincular dinamicamente o redist no runtime), consulte /MD, /MT/LD ( Use Run-Time Library).
Note
Na tabela a seguir, {arch} é ou i386x86_64.
Essas bibliotecas usam convenções Clang para nomes de arquitetura. As convenções MSVC são normalmente x86 e x64 em vez de i386 e x86_64, mas se referem às mesmas arquiteturas.
| Opção CRT | Biblioteca de runtime do AddressSanitizer (.lib) |
Binário de runtime de endereço (.dll) |
|---|---|---|
/MT ou /MTd |
clang_rt.asan_dynamic-{arch}, clang_rt.asan_static_runtime_thunk-{arch} |
clang_rt.asan_dynamic-{arch} |
/MD ou /MDd |
clang_rt.asan_dynamic-{arch}, clang_rt.asan_dynamic_runtime_thunk-{arch} |
clang_rt.asan_dynamic-{arch} |
O diagrama a seguir mostra como as bibliotecas de tempo de execução de linguagem são vinculadas para as /MTopções , /MTd, /MD, e /MDd do compilador:
A imagem mostra três cenários para vincular a biblioteca de tempo de execução. O primeiro é /MT ou /MTd. My_exe.exe e my_dll.dll são mostrados com suas próprias cópias dos tempos de execução VCRuntime, Universal CRT e C++ vinculados estaticamente. Os cenários mostram /MD em que my_exe.exe e my_dll.dll compartilham vcruntime140.dll, ucrtbase.dll e msvcp140.dll. O último cenário mostra /MDd no qual my_exe.exe e my_dll.dll compartilham as versões de depuração dos runtimes: vcruntime140d.dll, ucrtbased.dll e msvcp140d.dll
O diagrama a seguir mostra como a biblioteca ASan está vinculada a várias opções do compilador:
A imagem mostra quatro cenários para vincular a biblioteca de tempo de execução do ASan. Os cenários são para /MT (vincular estaticamente o runtime), /MTd (vincular estaticamente o runtime de depuração), /MD (vincular dinamicamente o redist em runtime), /MDd (vincular dinamicamente o redist de depuração em runtime). Em todos os casos, my_exe.exe links e seus associados my_dll.dll link para uma única instância de clang_rt.asan_dynamic-x86_64.dll.
Mesmo ao vincular estaticamente, a DLL de runtime do ASan deve estar presente no runtime, ao contrário de outros componentes do C Runtime.
Versões anteriores
Antes do Visual Studio 17.7 Versão Prévia 3, os builds vinculados estaticamente (/MT ou /MTd) não usavam uma dependência de DLL. Em vez disso, o tempo de execução do AddressSanitizer foi vinculado estaticamente ao EXE do usuário. Os projetos DLL carregariam as exportações do EXE do usuário para acessar a funcionalidade ASan.
Projetos vinculados dinamicamente (/MD ou /MDd) usavam bibliotecas e DLLs diferentes, dependendo se o projeto estava configurado para depuração ou versão. Para obter mais informações sobre essas alterações e suas motivações, consulte MSVC AddressSanitizer – Uma DLL para todas as Configurações de Runtime.
A tabela a seguir descreve o comportamento anterior da vinculação da biblioteca de runtime AddressSanitizer, antes do Visual Studio 17.7 Preview 3:
| Opção CRT | DLL ou EXE | DEBUG? | Uma biblioteca (.lib) |
Binário de tempo de execução do 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} |
O diagrama a seguir mostra como a biblioteca ASan foi vinculada para várias opções do compilador antes do Visual Studio 2022 17.7 Versão Prévia 3:
A imagem mostra quatro cenários para vincular a biblioteca de tempo de execução do ASan. Os cenários são para /MT (vincular estaticamente o runtime), /MTd (vincular estaticamente o runtime de depuração), /MD (vincular dinamicamente o redist em runtime), /MDd (vincular dinamicamente o redist de depuração em runtime). Para /MT, my_exe.exe tem uma cópia vinculada estaticamente do tempo de execução do ASan. my_dll.dll links para o tempo de execução do ASan no my_exe.exe. Para /MTd, o diagrama é o mesmo, exceto que ele usa o runtime de depuração vinculado estaticamente do ASan. Para /MD, my_exe.exe e my_dll.dll vinculam ao runtime do ASan vinculado dinamicamente chamado clang_rt.asan_dynamic-x86_64.dll. Para /MDd, o diagrama é o mesmo, exceto my_exe.exe e my_dll.dll link para o runtime de depuração do ASan chamado clang_rt.asan_dbg_dynamic-x86_64.dll.
Interceptação de função
O AddressSanitizer obtém interceptação de função por meio de muitas técnicas de hotpatching. Essas técnicas são mais bem-documentadas dentro do próprio código-fonte.
As bibliotecas de runtime interceptam muitas funções comuns de gerenciamento de memória e manipulação de memória. Para obter uma lista, consulte a lista AddressSanitizer de funções interceptadas. Os interceptadores de alocação gerenciam metadados e bytes de sombra relacionados a cada chamada de alocação. Sempre que uma função CRT, como malloc ou delete é chamada, os interceptadores definem valores específicos na região de memória sombra do AddressSanitizer para indicar se esses locais de heap estão acessíveis no momento e quais são os limites da alocação. Esses bytes de sombra permitem que as verificações geradas pelo compilador dos bytes de sombra determinem se uma carga ou repositório é válido.
A interceptação não tem garantia de sucesso. Se um prólogo de função for muito curto para um jmp ser gravado, a interceptação poderá falhar. Se ocorrer uma falha de interceptação, o programa lançará um debugbreak e interromperá. Se você anexar um depurador, isso torna clara a causa do problema de interceptação. Se você tiver esse problema, relate um bug.
Note
Opcionalmente, os usuários podem tentar continuar após uma interceptação com falha definindo a variável de ambiente ASAN_WIN_CONTINUE_ON_INTERCEPTION_FAILURE como qualquer valor. Continuar após uma falha de interceptação pode resultar em relatórios de bugs perdidos para essa função.
Alocadores personalizados e o runtime addressSanitizer
O runtime do AddressSanitizer fornece interceptadores para interfaces comuns do alocador, malloc/free, new/delete, HeapAlloc/HeapFree (via RtlAllocateHeap/RtlFreeHeap). Muitos programas usam alocadores personalizados por um motivo ou outro, um exemplo seria qualquer programa usando dlmalloc ou uma solução usando a interface std::allocator e VirtualAlloc(). O compilador não pode adicionar automaticamente chamadas de gerenciamento de memória de sombra a um alocador personalizado. É responsabilidade do usuário usar a interface de envenenamento manual fornecida. Essa API permite que esses alocadores funcionem corretamente com o runtime do AddressSanitizer e as convenções de bytes de sombra existentes.
Interface de envenenamento do AddressSanitizer manual
A interface de esclarecimento é simples, mas impõe restrições de alinhamento ao usuário. Os usuários podem importar esses protótipos importando sanitizer/asan_interface.h. Aqui estão os protótipos da função de interface:
void __asan_poison_memory_region(void const volatile *addr, size_t size);
void __asan_unpoison_memory_region(void const volatile *addr, size_t size);
Para conveniência, o arquivo de cabeçalho da interface AddressSanitizer fornece macros de encapsulamento. Essas macros verificam se a funcionalidade AddressSanitizer está habilitada durante a compilação. Eles permitem que o código-fonte omita as chamadas de função de envenenamento quando não são necessárias. Essas macros devem ser preferenciais ao chamar diretamente as funções acima:
#define ASAN_POISON_MEMORY_REGION(addr, size)
#define ASAN_UNPOISON_MEMORY_REGION(addr, size)
Note
Se você envenenar manualmente a memória, você deve desponsá-la antes de reutilizá-la. Isso é especialmente importante para endereços de pilha, como para uma variável local, que são reutilizados com frequência durante a execução do programa. Você corre o risco de use-after-poison introduzir falsos positivos em endereços de pilha envenenados manualmente se não despomá-los antes que o quadro de pilha seja removido.
Requisitos de alinhamento para envenenamento por AddressSanitizer
Qualquer envenenamento manual de bytes de sombra deve considerar os requisitos de alinhamento. O usuário deve adicionar preenchimento, se necessário, para que os bytes de sombra terminem em um limite de bytes na memória de sombra. Cada bit na memória de sombra addressSanitizer codifica o estado de um único byte na memória do aplicativo. Essa codificação significa que o tamanho total de cada alocação, incluindo qualquer preenchimento, deve se alinhar a um limite de 8 bytes. Se o requisito de alinhamento não for atendido, ele poderá levar a relatórios de bug incorretos. O relatório incorreto pode se manifestar como relatórios ausentes (falsos negativos) ou relatórios sobre não erros (falsos positivos).
Para obter uma ilustração do requisito de alinhamento e possíveis problemas, consulte os exemplos de alinhamento ASan fornecidos. Um deles é um pequeno programa para mostrar o que pode dar errado com envenenamento manual de memória de sombra. A segunda é uma implementação de exemplo de envenenamento manual usando a interface std::allocator.
Opções de runtime
O AddressSanitizer do MSVC é um fork sincronizado regularmente do runtime do Clang AddressSanitizer. Como resultado, o MSVC herda implicitamente muitas das opções de runtime do ASan do Clang. Uma lista completa de opções que mantemos e testamos ativamente pode ser encontrada aqui. Se você descobrir opções que não funcionam conforme o esperado, relate um bug.
Configurar opções de runtime
As opções de runtime do ASan são definidas de duas maneiras:
- A variável de ambiente
ASAN_OPTIONS - A
__asan_default_optionsfunção de usuário
Se a variável de ambiente e a função de usuário especificar opções conflitantes, as opções na variável de ASAN_OPTIONS ambiente têm precedência.
Várias opções são especificadas separando-as com dois-pontos (:).
O exemplo a seguir define alloc_dealloc_mismatch como um e symbolize como zero:
set ASAN_OPTIONS=alloc_dealloc_mismatch=1:symbolize=0
Ou adicione a seguinte função ao código:
extern "C" const char* __asan_default_options()
{
return "alloc_dealloc_mismatch=1:symbolize=0";
}
Opções do AddressSanitizer sem suporte
detect_container_overflowunmap_shadow_on_exit
Note
A opção halt_on_error de runtime addressSanitizer não funciona conforme esperado. Nas bibliotecas de runtime do Clang e do MSVC, muitos tipos de erro são considerados não contínuos, incluindo a maioria dos erros de corrupção de memória.
Para obter mais informações, consulte a seção Diferenças com Clang 12.0.
Opções de runtime do AddressSanitizer específicas do MSVC
continue_on_errorBooliano, definido comofalsepor padrão. Quando definido comotrue, ele permite que o programa continue em execução depois que uma violação de memória é relatada, permitindo que você colete vários relatórios de erro.iat_overwriteString, definida como"error"por padrão. Outros valores possíveis são"protect"e"ignore". Alguns módulos podem substituir oimport address tablede outros módulos para personalizar implementações de determinadas funções. Por exemplo, os drivers geralmente fornecem implementações personalizadas para hardware específico. Aiat_overwriteopção gerencia a proteção do runtime do AddressSanitizer contra substituições para funções específicasmemoryapi.h. Atualmente, o runtime rastreia asVirtualAllocfunções ,VirtualProtect, eVirtualQuerypara proteção. Essa opção está disponível no Visual Studio 2022 versão 17.5 Versão Prévia 1 e versões posteriores. Os valores a seguiriat_overwritecontrolam como o runtime reage quando as funções protegidas são substituídas:- Se definido como
"error"(o padrão), o runtime relata um erro sempre que uma substituição é detectada. - Se definido como
"protect", o runtime tentará evitar o uso da definição substituída e continuará. Efetivamente, a definição originalmemoryapida função é usada de dentro do runtime para evitar recursão infinita. Outros módulos no processo ainda usam a definição substituída. - Se definido como
"ignore", o runtime não tentará corrigir nenhuma função substituída e continuará com a execução.
- Se definido como
windows_fast_fail_on_errorBooliano (falsepor padrão), definido paratruepermitir que o processo seja encerrado com um__fastfail(71)após a impressão do relatório de erros.Note
Quando
abort_on_erroro valor é definido comotrue, no Windows, o programa termina com umexit(3). Para não alterar o comportamento atual, decidimos introduzir essa nova opção. Se ambosabort_on_errorewindows_fast_fail_on_errorestiveremtrue, o programa sairá com o__fastfail.windows_hook_legacy_allocatorsBooleano, definido comofalsepara desabilitar a interceptação deGlobalAlloceLocalAllocalocadores.Note
A opção
windows_hook_legacy_allocatorsnão estava disponível no runtime público do projeto llvm quando este artigo foi redigido. A opção pode eventualmente ser contribuída de volta para o projeto público; no entanto, depende da revisão de código e da aceitação da comunidade.A opção
windows_hook_rtl_allocators, anteriormente um recurso de aceitação enquanto AddressSanitizer era experimental, agora está habilitada por padrão. Em versões anteriores ao Visual Studio 2022 versão 17.4.6, o valor da opção padrão éfalse. No Visual Studio 2022 versão 17.4.6 e versões posteriores, o padrão da opçãowindows_hook_rtl_allocatorsétrue.
Lista do AddressSanitizer de funções interceptadas (Windows)
O tempo de execução do AddressSanitizer corrige muitas funções para habilitar verificações de segurança de memória no tempo de execução. Aqui está uma lista, que não é definitiva, das funções que o runtime do AddressSanitizer monitora.
Interceptadores padrão
-
__C_specific_handler(somente x64) _aligned_free_aligned_malloc_aligned_msize_aligned_realloc_calloc_base_calloc_crt-
_calloc_dbg(somente runtime de depuração) -
_except_handler3(somente x86) -
_except_handler4(somente x86) (não documentado) _expand-
_expand_base(não documentado) -
_expand_dbg(somente runtime de depuração) -
_free_base(não documentado) -
_free_dbg(somente runtime de depuração) -
_malloc_base(não documentado) -
_malloc_crt(não documentado) -
_malloc_dbg(somente runtime de depuração) _msize-
_msize_base(não documentado) -
_msize_dbg(somente runtime de depuração) -
_realloc_base(não documentado) -
_realloc_crt(não documentado) -
_realloc_dbg(somente runtime de depuração) _recalloc-
_recalloc_base(não documentado) -
_recalloc_crt(não documentado) -
_recalloc_dbg(somente runtime de depuração) _strdupatoiatolcallocCreateThreadfreefrexplongjmpmallocmemchrmemcmpmemcpymemmovememsetRaiseExceptionreallocRtlAllocateHeapRtlCreateHeapRtlDestroyHeapRtlFreeHeapRtlRaiseException-
RtlReAllocateHeap(não documentado) -
RtlSizeHeap(não documentado) SetUnhandledExceptionFilterstrcatstrchrstrcmpstrcpystrcspnstrdupstrlenstrncatstrncmpstrncpystrnlenstrpbrkstrspnstrstrstrtokstrtolwcslenwcsnlen
Interceptores opcionais
Os interceptadores listados aqui só são instalados quando uma opção de runtime do AddressSanitizer está habilitada. Defina windows_hook_legacy_allocators como false para desabilitar a interceptação do alocador herdado.
set ASAN_OPTIONS=windows_hook_legacy_allocators=false
GlobalAllocGlobalFreeGlobalHandleGlobalLockGlobalReAllocGlobalSizeGlobalUnlockLocalAllocLocalFreeLocalHandleLocalLockLocalReAllocLocalSizeLocalUnlock
Consulte também
Visão geral do AddressSanitizer
Problemas conhecidos do AddressSanitizer
Referência de linguagem e build do AddressSanitizer
Bytes de sombra de AddressSanitizer
Nuvem do AddressSanitizer ou teste distribuído
Integração do depurador do AddressSanitizer
Exemplos de erro do AddressSanitizer