Partager via


Informations de référence sur le langage AddressSanitizer, la génération et le débogage

Les sections de cet article décrivent la spécification du langage AddressSanitizer, les options du compilateur et les options de l’éditeur de liens. Ils décrivent également les options qui contrôlent l’intégration du débogueur Visual Studio spécifique à AddressSanitizer.

Pour plus d’informations sur le runtime AddressSanitizer, consultez la référence du runtime. Il inclut des informations sur les fonctions interceptées et la façon de raccorder des allocateurs personnalisés. Pour plus d’informations sur l’enregistrement des vidages sur incident à partir des échecs AddressSanitizer, consultez la référence de vidage sur incident.

Spécification du langage

__SANITIZE_ADDRESS__

La __SANITIZE_ADDRESS__ macro de préprocesseur est définie comme 1 lorsqu’elle /fsanitize=address est définie. Cette macro est utile pour que les utilisateurs avancés spécifient de manière conditionnelle le code source pour la présence du runtime 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)

Le __declspec(no_sanitize_address) spécificateur peut être utilisé pour désactiver de manière sélective le nettoyage sur les fonctions, les variables locales ou les variables globales. Cela __declspec affecte le comportement du compilateur , et non le comportement d’exécution .

__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
}

Compilateur

Option de compilateur /fsanitize=address

L’option /fsanitize=address du compilateur instrumente les références de mémoire dans votre code pour intercepter les erreurs de sécurité de la mémoire au moment de l’exécution. Les hooks d’instrumentation chargent, stocke, étendues allocaet fonctions CRT. Il peut détecter les bogues masqués tels que les limites hors limites, l’utilisation après l’utilisation, l’utilisation après étendue, etc. Pour obtenir une liste non exhaustive des erreurs détectées lors de l’exécution, consultez les exemples d’erreurs AddressSanitizer.

/fsanitize=addressest compatible avec tous les niveaux d’optimisation C++ ou C existants (par exemple, , /Od, /O1/O2et /O2 /GL). Le code généré avec cette option fonctionne avec des CRT statiques et dynamiques (par exemple, , /MD/MDd, /MTet /MTd). Cette option de compilateur peut être utilisée pour créer une .EXE ou .DLL ciblant x86 ou x64. Les informations de débogage sont requises pour une mise en forme optimale des piles d’appels. Cette option de compilateur n’est pas prise en charge avec l’optimisation guidée par profil.

Pour obtenir des exemples de code qui illustre plusieurs types de détection d’erreurs, consultez exemples d’erreurs AddressSanitizer.

/fsanitize=fuzzer Option du compilateur (expérimentale)

L’option /fsanitize=fuzzer du compilateur ajoute LibFuzzer à la liste de bibliothèques par défaut. Il définit également les options de couverture de nettoyage suivantes :

Nous vous recommandons d’utiliser /fsanitize=address avec /fsanitize=fuzzer.

Ces bibliothèques sont ajoutées à la liste de bibliothèques par défaut lorsque vous spécifiez /fsanitize=fuzzer:

Runtime Bibliothèque 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}

Les bibliothèques LibFuzzer qui omettent la main fonction sont également disponibles. Il vous incombe de définir main et d’appeler LLVMFuzzerInitialize et LLVMFuzzerTestOneInput quand vous utilisez ces bibliothèques. Pour utiliser l’une de ces bibliothèques, spécifiez et associez /NODEFAULTLIB explicitement la bibliothèque suivante qui correspond à votre runtime et à votre architecture :

Runtime Bibliothèque no_main 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}

Si vous spécifiez /NODEFAULTLIB et que vous ne spécifiez pas l’une de ces bibliothèques, vous obtenez une erreur de lien de symbole externe non résolue.

/fsanitize-address-use-after-return Option du compilateur (expérimentale)

Par défaut, le compilateur MSVC (contrairement à Clang) ne génère pas de code pour allouer des images dans le tas pour intercepter les erreurs d’utilisation après retour. Pour intercepter ces erreurs à l’aide de AddressSanitizer, vous devez :

  1. Compilez à l’aide de l’option /fsanitize-address-use-after-return .
  2. Avant d’exécuter votre programme, exécutez set ASAN_OPTIONS=detect_stack_use_after_return=1 pour définir l’option de vérification du runtime.

L’option /fsanitize-address-use-after-return amène le compilateur à générer du code pour utiliser une trame double pile dans le tas lorsque les locaux sont considérés comme « adresse prise ». Ce code est beaucoup plus lent que l’utilisation /fsanitize=address seule. Pour plus d’informations et un exemple, consultez Erreur : stack-use-after-return.

Le cadre double pile dans le tas reste après le retour de la fonction qui l’a créée. Prenons un exemple où l’adresse d’un emplacement local, alloué à un emplacement dans le tas, est utilisée après le retour. Les octets d’ombre associés au cadre de tas faux contiennent la valeur 0xF9. Cette 0xF9 signifie une erreur stack-use-after-return lorsque le runtime signale l’erreur.

Les images de pile sont allouées dans le tas et restent après le retour des fonctions. Le runtime utilise le garbage collection pour libérer de façon asynchrone ces faux objets d’image d’appel, après un certain intervalle de temps. Les adresses des locaux sont transférées vers des images persistantes dans le tas. Il s’agit de la façon dont le système peut détecter quand tous les locaux sont utilisés après le retour de la fonction de définition. Pour plus d’informations, consultez l’algorithme pour l’utilisation de la pile après le retour tel que documenté par Google.

Éditeur de liens

/INFERASANLIBS[:NO] Option éditeur de liens

L’option /fsanitize=address du compilateur marque les objets pour spécifier la bibliothèque AddressSanitizer à lier à votre exécutable. Les bibliothèques ont des noms qui commencent par clang_rt.asan*. L’option /INFERASANLIBS éditeur de liens (activée par défaut) lie automatiquement ces bibliothèques à partir de leurs emplacements par défaut. Voici les bibliothèques choisies et automatiquement liées.

Remarque

Dans le tableau suivant, {arch} est soit i386 .x86_64 Ces bibliothèques utilisent des conventions Clang pour les noms d’architecture. Les conventions MSVC sont normalement x86 et x64 plutôt que i386 .x86_64 Ils font référence aux mêmes architectures.

Option CRT Bibliothèque runtime AddressSanitizer (.lib) Binaire du runtime d’adresse (.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}

L’option /INFERASANLIBS:NO éditeur de liens empêche l’éditeur de liens de lier un clang_rt.asan* fichier de bibliothèque à partir de l’emplacement par défaut. Ajoutez le chemin d’accès de la bibliothèque dans vos scripts de build si vous utilisez cette option. Sinon, l’éditeur de liens signale une erreur de symbole externe non résolue.

Versions précédentes

Avant Visual Studio 17.7 Preview 3, les builds liées statiquement (/MT ou /MTd) n’utilisaient pas de dépendance DLL. Au lieu de cela, le runtime AddressSanitizer était lié statiquement à l’EXE de l’utilisateur. Les projets DLL chargent ensuite les exportations à partir de l’EXE de l’utilisateur pour accéder aux fonctionnalités ASan. En outre, les projets liés dynamiquement (/MD ou /MTd) utilisaient différentes bibliothèques et DLL selon que le projet a été configuré pour le débogage ou la mise en production. Pour plus d’informations sur ces modifications et leurs motivations, consultez MSVC Address Sanitizer – One DLL for all Runtime Configurations.

Option d’exécution CRT DLL ou EXE Bibliothèques runtime AddressSanitizer
/MT EXE clang_rt.asan-{arch}, clang_rt.asan_cxx-{arch}
/MT DLL clang_rt.asan_dll_thunk-{arch}
/MD Vous pouvez soit utiliser 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 Vous pouvez soit utiliser clang_rt.asan_dbg_dynamic-{arch}, clang_rt.asan_dbg_dynamic_runtime_thunk-{arch}

Intégration de Visual Studio

Option de compilateur /fno-sanitize-address-vcasan-lib

L’option /fsanitize=address établit des liens dans des bibliothèques supplémentaires pour une expérience de débogage Visual Studio améliorée lorsqu’une exception AddressSanitizer est levée. Ces bibliothèques sont appelées VCAsan. Les bibliothèques permettent à Visual Studio d’afficher les erreurs AddressSanitizer sur votre code source. Ils permettent également à l’exécutable de générer des vidages sur incident lorsqu’un rapport d’erreur AddressSanitizer est créé. Pour plus d’informations, consultez la bibliothèque de fonctionnalités étendues de Visual Studio AddressSanitizer.

La bibliothèque choisie dépend des options du compilateur et est automatiquement liée.

Runtime Version VCAsan
/MT libvcasan.lib
/MD vcasan.lib
/MTd libvcasand.lib
/MDd vcasand.lib

Toutefois, si vous compilez à l’aide /Zl (omettez le nom de la bibliothèque par défaut), vous devez spécifier manuellement la bibliothèque. Si ce n’est pas le cas, vous obtiendrez une erreur de lien de symbole externe non résolue. Voici quelques exemples type :

error LNK2001: unresolved external symbol __you_must_link_with_VCAsan_lib
error LNK2001: unresolved external symbol ___you_must_link_with_VCAsan_lib

Le débogage amélioré peut être désactivé au moment de la compilation à l’aide de l’option /fno-sanitize-address-vcasan-lib .

ASAN_VCASAN_DEBUGGING variable d’environnement

L’option /fsanitize=address du compilateur produit un binaire qui expose les bogues de sécurité de la mémoire au moment de l’exécution. Lorsque le binaire est démarré à partir de la ligne de commande et que le runtime signale une erreur, il imprime les détails de l’erreur. Il quitte ensuite le processus. La ASAN_VCASAN_DEBUGGING variable d’environnement peut être définie pour lancer l’IDE Visual Studio immédiatement lorsque le runtime signale une erreur. Cette option de compilateur vous permet d’afficher l’erreur, superposée sur votre code source, à la ligne et à la colonne précises qui ont provoqué l’erreur.

Pour activer ce comportement, exécutez la commande set ASAN_VCASAN_DEBUGGING=1 avant d’exécuter votre application. Vous pouvez désactiver l’expérience de débogage améliorée en exécutant set ASAN_VCASAN_DEBUGGING=0.

Voir aussi

Vue d’ensemble de AddressSanitizer
Résoudre les problèmes connus liés à AddressSanitizer
Informations de référence sur le runtime AddressSanitizer
Octets d’ombre AddressSanitizer
Test cloud ou distribué AddressSanitizer
Intégration du débogueur AddressSanitizer
Exemples d’erreur AddressSanitizer