Referência de linguagem, compilação e depuração do AddressSanitizer

As seções neste artigo descrevem a especificação da linguagem AddressSanitizer, as opções do compilador e as opções do vinculador. elas também descrevem as opções que controlam a integração do depurador Visual Studio específica ao AddressSanitizer.

Para obter mais informações sobre o tempo de execução do AddressSanitizer, consulte a referência de tempo de execução. Ele inclui informações sobre as funções interceptadas e como conectar alocadores personalizados. Para obter mais informações sobre como salvar despejos de memória de falhas do AddressSanitizer, consulte a referência de despejode memória.

Especificação do idioma

__SANITIZE_ADDRESS__

A macro de __SANITIZE_ADDRESS__ pré-processador é definida como 1 quando /fsanitize=address é definido. Essa macro é útil para que usuários avançados especifiquem condicionalmente o código-fonte para a presença do tempo de execução AddressSanitizer.

#include <cstdio>

int main() {
    #ifdef __SANITIZE_ADDRESS__
        printf("Address sanitizer enabled");
    #else
        printf("Address sanitizer not enabled");
    #endif
    return 1;
}

__declspec(no_sanitize_address)

O __declspec(no_sanitize_address) especificador pode ser usado para desabilitar seletivamente o limpador em funções, variáveis locais ou variáveis globais. Isso afeta o __declspec comportamento do compilador , não o comportamento do tempo de execução .

__declspec(no_sanitize_address)
void test1() {
    int x[100];
    x[100] = 5; // ASan exception not caught
}

void test2() {
    __declspec(no_sanitize_address) int x[100];
    x[100] = 5; // ASan exception not caught
}

__declspec(no_sanitize_address) int g[100];
void test3() {
    g[100] = 5; // ASan exception not caught
}

Compilador

Opção do compilador /fsanitize=address

A opção do compilador instrumenta as /fsanitize=address referências de memória em seu código para capturar erros de segurança de memória em tempo de execução. Os ganchos de instrumentação carregam, armazena, escopos alloca , e as funções CRT. Ele pode detectar bugs ocultos, como fora de limites, usar-após-gratuito, usar-após-Scope e assim por diante. Para obter uma lista não exaustiva de erros detectados em tempo de execução, consulte exemplos de erro AddressSanitizer.

/fsanitize=address é compatível com todos os níveis de otimização existentes de C++ ou C (por exemplo, /Od/O1/O2/O2 /GL ,,, e otimização guiada por perfil). 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 de compilador pode ser usada para criar um .EXE ou .DLL direcionamento a x86 ou x64. As informações de depuração são necessárias para a formatação ideal de pilhas de chamadas.

Para obter exemplos de código que demonstra vários tipos de detecção de erros, consulte exemplos de erro AddressSanitizer.

/fsanitize=fuzzer opção do compilador (experimental)

A opção do /fsanitize=fuzzer compilador adiciona LibFuzzer à lista de biblioteca padrão. Ele também define as seguintes opções de cobertura de limpeza:

Recomendamos que você use /fsanitize=address com /fsanitize=fuzzer o.

Essas bibliotecas são adicionadas à lista de biblioteca 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}

As bibliotecas LibFuzzer que omitem a main função 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 com a biblioteca abaixo que corresponde ao seu tempo de execução e à sua arquitetura:

Opção de runtime Biblioteca de no_main de LibFuzzer
/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, obterá um erro de link de símbolo externo não resolvido.

/fsanitize-address-use-after-return opção do compilador (experimental)

por padrão, o compilador de MSVC (ao contrário de Clang) não gera código para alocar quadros no heap para capturar erros de uso posteriores. Para capturar esses erros usando o AddressSanitizer, você deve:

  1. Compile usando a /fsanitize-address-use-after-return opção.
  2. Antes de executar o programa, execute set ASAN_OPTIONS=detect_stack_use_after_return=1 para definir a opção de verificação de tempo de execução.

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ço tomado". Esse código é muito mais lento do que apenas usar /fsanitize=address sozinho. Para obter mais informações e um exemplo, consulte 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 para um slot no heap, seja usado após o retorno. Os bytes de sombra associados ao quadro de heap falso contêm o valor 0xF9. Isso 0xF9 significa um erro de uso de pilha-após-retorno quando o tempo de execução relata o erro.

Os quadros de pilha são alocados no heap e permanecem depois que as funções retornam. O tempo de execução usa a coleta de lixo para liberar de forma assíncrona esses objetos falsos de quadro de chamada, após um determinado intervalo de tempo. Endereços de locais são transferidos para quadros persistentes no heap. É assim que o sistema pode detectar quando quaisquer locais são usados depois que a função de definição retorna. Para obter mais informações, consulte o algoritmo para uso de pilha após o retorno , conforme documentado pelo Google.

Vinculador

/INFERASANLIBS[:NO] opção de vinculador

A opção do /fsanitize=address compilador marca os objetos para especificar a biblioteca AddressSanitizer a ser vinculada ao seu executável. As bibliotecas têm nomes que começam com clang_rt.asan* . A /INFERASANLIBS opção de vinculador (ativada por padrão) vincula essas bibliotecas de seus locais padrão automaticamente. Estas são as bibliotecas escolhidas e vinculadas automaticamente em:

Opção de runtime DLL ou EXE Bibliotecas de tempo de execução AddressSanitizer
/MT EXE clang_rt.asan-{arch}, clang_rt.asan_cxx-{arch}
/MT DLL clang_rt.asan_dll_thunk-{arch}
/MD QUALQUER UM clang_rt.asan_dynamic-{arch}, clang_rt.asan_dynamic_runtime_thunk-{arch}
/MTd EXE clang_rt.asan_dbg-{arch}, clang_rt.asan_dbg_cxx-{arch}
/MTd DLL clang_rt.asan_dbg_dll_thunk-{arch}
/MDd QUALQUER UM clang_rt.asan_dbg_dynamic-{arch}, clang_rt.asan_dbg_dynamic_runtime_thunk-{arch}

A opção /INFERASANLIBS:NO de vinculador impede que o vinculador vincule um clang_rt.asan* arquivo de biblioteca do local padrão. Adicione o caminho da biblioteca em seus scripts de compilação se você usar essa opção. Caso contrário, o vinculador relatará um erro de símbolo externo não resolvido.

integração com o Visual Studio

Opção do compilador /fno-sanitize-address-vcasan-lib

a opção se vincula a /fsanitize=address bibliotecas extras para uma experiência de depuração de Visual Studio aprimorada quando uma exceção AddressSanitizer é lançada. Essas bibliotecas são chamadas de VCAsan. as bibliotecas permitem Visual Studio exibir erros de AddressSanitizer no código-fonte. Eles também permitem que o executável gere despejos de memória quando um relatório de erro AddressSanitizer é criado. para obter mais informações, consulte Visual Studio biblioteca de funcionalidades estendidas do AddressSanitizer.

A biblioteca escolhida depende das opções do compilador e é vinculada automaticamente.

Opção de runtime Versão do VCAsan
/MT libvcasan.lib
/MD vcasan.lib
/MTd libvcasand.lib
/MDd vcasand.lib

No entanto, se você compilar usando /Zl (omitir o nome da biblioteca padrão), será necessário especificar manualmente a biblioteca. Caso contrário, você obterá 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 /fno-sanitize-address-vcasan-lib opção.

A variável de ambiente ASAN_VCASAN_DEBUGGING

A opção do /fsanitize=address compilador produz um binário que expõe bugs de segurança de memória em tempo de execução. Quando o binário é iniciado na linha de comando e o tempo de execução relata um erro, ele imprime os detalhes do erro. Em seguida, ele sai do processo. a ASAN_VCASAN_DEBUGGING variável de ambiente pode ser definida para iniciar o Visual Studio IDE imediatamente quando o tempo de execução relata um erro. Essa opção de compilador permite exibir o erro, sobreposto ao seu 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 o aplicativo. Você pode desabilitar a experiência de depuração avançada executando set ASAN_VCASAN_DEBUGGING=0 o.

Confira também

Visão geral do AddressSanitizer
Problemas conhecidos do AddressSanitizer
Referência de runtime do AddressSanitizer
Bytes de sombra do AddressSanitizer
AddressSanitizer cloud ou distributed testing
Integração do depurador AddressSanitizer
Exemplos de erro addressSanitizer