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.
Este artigo descreve a especificação da linguagem AddressSanitizer do MSVC, as opções do compilador, as opções do vinculador e as opções que controlam a integração do depurador do Visual Studio específica ao AddressSanitizer do MSVC.
Para obter mais informações sobre o runtime do AddressSanitizer do MSVC, consulte a referência de runtime. Ela inclui informações sobre funções interceptadas e como conectar alocadores personalizados. Para obter mais informações sobre como salvar despejos de memória de falhas do AddressSanitizer do MSVC, consulte a referência de despejo de memória.
Especificação do idioma
__SANITIZE_ADDRESS__
A macro __SANITIZE_ADDRESS__ do pré-processador é definida como 1 quando /fsanitize=address está definido. Essa macro é útil para especificar condicionalmente o código-fonte para a presença do runtime do AddressSanitizer do MSVC.
#include <cstdio>
int main()
{
#ifdef __SANITIZE_ADDRESS__
printf("MSVC AddressSanitizer enabled");
#else
printf("MSVC AddressSanitizer not enabled");
#endif
return 1;
}
__declspec(no_sanitize_address)
O especificador __declspec(no_sanitize_address) pode ser usado para desabilitar seletivamente o Sanitizer em funções, variáveis locais ou variáveis globais. Esse __declspec afeta o comportamento do compilador e não o comportamento de runtime.
#ifdef __SANITIZE_ADDRESS__
// no_sanitize_address is only defined when compiling with MSVC AddressSanitizer.
// Guard against this by checking if `__SANITIZE_ADDRESS__` is defined.
#define NO_SANITIZE_ADDRESS __declspec(no_sanitize_address)
#else
#define NO_SANITIZE_ADDRESS
#endif
NO_SANITIZE_ADDRESS
void test1()
{
int x[100];
x[100] = 5; // ASan exception not caught
}
void test2()
{
NO_SANITIZE_ADDRESS int x[100];
x[100] = 5; // ASan exception not caught
}
NO_SANITIZE_ADDRESS int g[100];
void test3()
{
g[100] = 5; // ASan exception not caught
}
Compiler
Opção do compilador /fsanitize=address
A opção de compilador /fsanitize=address instrumenta referências de memória no seu código para capturar erros de segurança de memória em runtime. As conexões de instrumentação conectam cargas, armazenam, definem o escopo, alloca, e funções CRT. Ela pode detectar bugs ocultos, como, por exemplo, fora dos limites, usar após liberação, usar após definição do escopo e assim por diante. Para obter uma lista não completa de erros detectados no runtime, consulte exemplos de erro do AddressSanitizer do MSVC.
/fsanitize=addressé compatível com todos os níveis de otimização C++ ou C existentes (por exemplo, /Od, , /O1/O2, e /O2 /GL). O código produzido com essa opção funciona com CRTs estáticos e dinâmicos (por exemplo, /MD, /MDd, /MT e /MTd). Essa opção do compilador pode ser usada para criar um .EXE ou .DLL visando x86 ou x64. As informações de depuração são necessárias para a formatação ideal das pilhas de chamadas. Essa opção do compilador não tem suporte com otimização guiada por perfil.
Para obter exemplos de código que demonstram vários tipos de detecção de erros, consulte exemplos de erro addressSanitizer do MSVC.
Opção do compilador /fsanitize=fuzzer (experimental)
A opção do compilador /fsanitize=fuzzer adiciona LibFuzzer à lista de bibliotecas padrão. Ela também define as seguintes opções de cobertura do Sanitizer:
-
Pontos de instrumentação de borda (
/fsanitize-coverage=edge), -
contadores embutidos de 8 bits (
/fsanitize-coverage=inline-8bit-counters), -
comparações (
/fsanitize-coverage=trace-cmp) e -
divisões de inteiros (
/fsanitize-coverage=trace-div).
Recomendamos o uso de /fsanitize=address com /fsanitize=fuzzer.
Essas bibliotecas são adicionadas à lista de bibliotecas padrão quando você especifica /fsanitize=fuzzer:
| Opção de runtime | Biblioteca LibFuzzer |
|---|---|
/MT |
clang_rt.fuzzer_MT-{arch} |
/MD |
clang_rt.fuzzer_MD-{arch} |
/MTd |
clang_rt.fuzzer_MTd-{arch} |
/MDd |
clang_rt.fuzzer_MDd-{arch} |
Bibliotecas LibFuzzer que omitem a função main também estão disponíveis. É sua responsabilidade definir main e chamar LLVMFuzzerInitialize e LLVMFuzzerTestOneInput quando você usa essas bibliotecas. Para usar uma dessas bibliotecas, especifique /NODEFAULTLIB e vincule explicitamente à seguinte biblioteca que corresponde ao seu tempo de execução e arquitetura:
| Opção de runtime | Biblioteca LibFuzzer no_main |
|---|---|
/MT |
clang_rt.fuzzer_no_main_MT-{arch} |
/MD |
clang_rt.fuzzer_no_main_MD-{arch} |
/MTd |
clang_rt.fuzzer_no_main_MTd-{arch} |
/MDd |
clang_rt.fuzzer_no_main_MDd-{arch} |
Se você especificar /NODEFAULTLIB e não especificar uma dessas bibliotecas, receberá um erro de link de símbolo externo não resolvido.
Opção do compilador /fsanitize-address-use-after-return (experimental)
Por padrão, o compilador MSVC (ao contrário de Clang) não gera código para alocar quadros no heap para capturar erros de uso após o retorno. Para capturar esses erros usando o AddressSanitizer do MSVC, você deve:
- Compile usando a opção
/fsanitize-address-use-after-return. - Antes de executar seu programa, execute
set ASAN_OPTIONS=detect_stack_use_after_return=1para definir a opção de verificação de runtime.
A /fsanitize-address-use-after-return opção faz com que o compilador gere código para usar um quadro de pilha dupla no heap quando os locais são considerados "endereços obtidos". Este código é muito mais lento do que apenas usar /fsanitize=address sozinho. Para obter mais informações e um exemplo, confira Erro: stack-use-after-return.
O quadro de pilha dupla no heap permanece após o retorno da função que o criou. Considere um exemplo em que o endereço de um local, alocado a um slot no heap, é usado após o retorno. Os bytes de sombra associados ao quadro de heap falso contêm o valor 0xF9. Esse 0xF9 significa um erro stack-use-after-return quando o runtime relata o erro.
Os quadros de pilha são alocados no heap e permanecem após o retorno das funções. O runtime usa a coleta de lixo para liberar de forma assíncrona esses objetos falsos de quadro de chamadas, após um determinado intervalo de tempo. Endereços de moradores são transferidos para quadros persistentes no heap. É como o sistema pode detectar quando qualquer local é usado após o retorno da função de definição. Para obter mais informações, consulte o algoritmo para uso de pilha após o retorno, conforme documentado pelo Google.
Biblioteca de compatibilidade intrínseca do ASan
Ao criar com o ASan, o compilador substitui funções intrínsecas (como memset) por chamadas de função fornecidas pela biblioteca de runtime do ASan (como __asan_memset) que completam a mesma operação, mas também fornecem verificações de segurança de memória. Para o ASan no modo de usuário, o compilador e o runtime são atualizados juntos porque o Visual Studio fornece ambos.
O KASan (Kernel-mode ASan) faz parte do sistema operacional Windows, portanto, ele é atualizado em uma cadência diferente do compilador. Para evitar problemas com um novo compilador usando novos intrínsecos aos quais a versão instalada do KASan não dá suporte, vincule a biblioteca de compatibilidade (asan_compat.lib) para evitar problemas de tempo de vínculo. Ao usar asan_compat.lib, o programa se comporta como se os intrínsecos ASan sem suporte não sejam usados. A vinculação com uma biblioteca de runtime mais recente que dá suporte aos novos intrínsecos do ASan substitui as versões fornecidas por asan_compat.lib. Essa decisão é tomada no momento do link, portanto, é imperativo vincular-se à biblioteca KASan fornecida pelo SDK do Windows que corresponde à versão do sistema operacional que você está direcionando.
As seguintes opções têm suporte no Visual Studio 2022 17.14 Versão Prévia 2 e posterior:
- Para incluir essa biblioteca de compatibilidade como uma biblioteca padrão, use a opção do
/fsanitize-address-asan-compat-libcompilador. Essa opção é habilitada automaticamente ao usar/fsanitize=kernel-address. - Para recusar essa biblioteca de compatibilidade, use a opção do
/fno-sanitize-address-asan-compat-libcompilador.
No /fsanitize-address-asan-compat-lib momento, não há suporte para o uso para vincular um compilador mais recente a um runtime do ASan no modo de usuário mais antigo.
Linker
Opção de vinculador /INFERASANLIBS[:NO]
A /fsanitize=address opção do compilador marca objetos para especificar qual biblioteca addressSanitizer do MSVC será vinculável ao executável. As bibliotecas têm nomes que começam com clang_rt.asan*. A opção do vinculador /INFERASANLIBS (por padrão) vincula essas bibliotecas a partir de seus locais padrão automaticamente. Aqui estão as bibliotecas escolhidas e vinculadas automaticamente.
Observação
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. Elas se referem às mesmas arquiteturas.
| Opção CRT | Biblioteca de runtime do AddressSanitizer do MSVC (.lib) | Binário de tempo de execução de endereço (.dll) |
|---|---|---|
/MT ou /MTd |
clang_rt.asan_dynamic-{arch}.lib, /wholearchive:clang_rt.asan_static_runtime_thunk-{arch}.lib |
clang_rt.asan_dynamic-{arch}.dll |
/MD ou /MDd |
clang_rt.asan_dynamic-{arch}.lib, /wholearchive:clang_rt.asan_dynamic_runtime_thunk-{arch}.lib |
clang_rt.asan_dynamic-{arch}.dll |
A opção do vinculador /INFERASANLIBS:NO impede que o vinculador vincule um arquivo de biblioteca clang_rt.asan* do local padrão. Adicione o caminho da biblioteca em seus scripts de compilação se usar essa opção. Caso contrário, o vinculador relatará um erro de símbolo externo não resolvido. As bibliotecas de thunk de runtime devem ser vinculadas à opção /wholearchive aplicada.
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 runtime do AddressSanitizer do MSVC 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. Além disso, projetos vinculados dinamicamente (/MD ou /MTd) 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.
| Opção de tempo de execução do CRT | DLL ou EXE | Bibliotecas de runtime do AddressSanitizer do MSVC |
|---|---|---|
/MT |
EXE |
/wholearchive:clang_rt.asan-{arch}.lib, clang_rt.asan_cxx-{arch}.lib |
/MT |
DLL | /wholearchive:clang_rt.asan_dll_thunk-{arch}.lib |
/MD |
Você pode usar o |
clang_rt.asan_dynamic-{arch}.lib, /wholearchive:clang_rt.asan_dynamic_runtime_thunk-{arch}.lib |
/MTd |
EXE |
/wholearchive:clang_rt.asan_dbg-{arch}.lib, clang_rt.asan_cxx_dbg-{arch}.lib |
/MTd |
DLL | /wholearchive:clang_rt.asan_dbg_dll_thunk-{arch}.lib |
/MDd |
Você pode usar o |
/wholearchive:clang_rt.asan_dbg_dynamic-{arch}.lib, clang_rt.asan_dbg_dynamic_runtime_thunk-{arch}.lib |
integração com o Visual Studio
Opção do compilador /fno-sanitize-address-vcasan-lib
A /fsanitize=address opção é vinculada em bibliotecas extras para uma experiência de depuração aprimorada do Visual Studio quando uma exceção de AddressSanitizer do MSVC é gerada. Essas bibliotecas são chamadas de VCAsan. As bibliotecas permitem que o Visual Studio exiba erros do AddressSanitizer do MSVC no código-fonte. Eles também permitem que o executável gere despejos de memória quando um relatório de erro addressSanitizer do MSVC é criado. Para obter mais informações, consulte a biblioteca de funcionalidades estendidas addressSanitizer do MSVC do Visual Studio.
A biblioteca escolhida depende das opções do compilador e é vinculada automaticamente.
| Opção de runtime | Versão VCAsan |
|---|---|
/MT |
libvcasan.lib |
/MD |
vcasan.lib |
/MTd |
libvcasand.lib |
/MDd |
vcasand.lib |
No entanto, se você compilar usando /Zl (Omitir nome da biblioteca padrão), deverá especificar manualmente a biblioteca. Caso contrário, você receberá um erro de link de símbolo externo não resolvido. Aqui estão alguns exemplos típicos:
error LNK2001: unresolved external symbol __you_must_link_with_VCAsan_lib
error LNK2001: unresolved external symbol ___you_must_link_with_VCAsan_lib
A depuração aprimorada pode ser desabilitada em tempo de compilação usando a opção /fno-sanitize-address-vcasan-lib.
A variável de ambiente ASAN_VCASAN_DEBUGGING
A opção do compilador /fsanitize=address produz um binário que expõe bugs de segurança de memória em runtime. Quando o binário é iniciado na linha de comando e o runtime relata um erro, ele imprime os detalhes do erro. Em seguida, ele sai do processo. A variável de ambiente ASAN_VCASAN_DEBUGGING pode ser definida para iniciar o IDE do Visual Studio imediatamente quando o runtime relatar um erro. Essa opção do compilador permite exibir o erro, sobreposto ao código-fonte, na linha e coluna precisas que causaram o erro.
Para habilitar esse comportamento, execute o comando set ASAN_VCASAN_DEBUGGING=1 antes de executar seu aplicativo. Você pode desabilitar a experiência de depuração aprimorada executando set ASAN_VCASAN_DEBUGGING=0.
Confira também
Visão geral do AddressSanitizer do MSVC
Problemas conhecidos do AddressSanitizer do MSVC
Referência de runtime do AddressSanitizer do MSVC
Bytes de sombra do AddressSanitizer do MSVC
Nuvem do AddressSanitizer do MSVC ou teste distribuído
Integração do depurador do AddressSanitizer do MSVC
Exemplos de erro do AddressSanitizer do MSVC