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 alloca
et 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=address
est compatible avec tous les niveaux d’optimisation C++ ou C existants (par exemple, , /Od
, /O1
/O2
et /O2 /GL
). Le code généré avec cette option fonctionne avec des CRT statiques et dynamiques (par exemple, , /MD
/MDd
, /MT
et /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 :
- Points d’instrumentation de périphérie (
/fsanitize-coverage=edge
), - compteurs inline 8 bits (
/fsanitize-coverage=inline-8bit-counters
), - comparaisons (
/fsanitize-coverage=trace-cmp
), et - divisions entières (
/fsanitize-coverage=trace-div
).
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 :
- Compilez à l’aide de l’option
/fsanitize-address-use-after-return
. - 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