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:
- Pontos de instrumentação de borda (
/fsanitize-coverage=edge
), - contadores de 8 bits embutidos (
/fsanitize-coverage=inline-8bit-counters
), - comparações (
/fsanitize-coverage=trace-cmp
)e - divisões de inteiro (
/fsanitize-coverage=trace-div
).
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:
- Compile usando a
/fsanitize-address-use-after-return
opção. - 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