Lorsque l'outil HWASan détecte un bug de mémoire, le processus se termine avec abort() et un rapport est imprimé sur stderr et logcat. Comme tous les crashs natifs sur Android, les erreurs HWASan peuvent être trouvées sous /data/tombstones
.
Par rapport aux plantages natifs classiques, HWASan contient des informations supplémentaires dans le champ « Message d'abandon » situé en haut de la pierre tombale. Voir un exemple de crash basé sur le tas ci-dessous (pour les bogues de pile, voir la note ci-dessous pour les sections spécifiques à la pile).
Exemple de rapport
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** Build fingerprint: 'google/flame_hwasan/flame:Tiramisu/MASTER/7956676:userdebug/dev-keys' Revision: 'DVT1.0' ABI: 'arm64' Timestamp: 2019-04-24 01:13:22+0000 pid: 11154, tid: 11154, name: sensors@1.0-ser >>> /vendor/bin/hw/android.hardware.sensors@1.0-service <<< signal 6 (SIGABRT), code -1 (SI_QUEUE), fault addr -------- Abort message: '==9569==ERROR: HWAddressSanitizer: tag-mismatch on address 0x00433ae20045 at pc 0x00623ae2a9cc READ of size 1 at 0x00433ae20045 tags: 5b/83 (ptr/mem) in thread T0 #0 0x7240450c68 (/system/lib64/vndk-sp-R/libcutils.so+0x8c68) #1 0x723dffd490 (/vendor/lib64/sensors.ssc.so+0x34490) #2 0x723e0126e0 (/vendor/lib64/sensors.ssc.so+0x496e0) [...] [0x00433ae20040,0x00433ae20060) is a small unallocated heap chunk; size: 32 offset: 5 Cause: use-after-free 0x00433ae20045 is located 5 bytes inside of 10-byte region [0x00433ae20040,0x00433ae2004a) freed by thread T0 here: #0 0x72404d1b18 (/system/lib64/libclang_rt.hwasan-aarch64-android.so+0x10b18) #1 0x723af23040 (/vendor/lib64/libgralloccore.so+0x5040) #2 0x723af23fa4 (/vendor/lib64/libgralloccore.so+0x5fa4) [...] previously allocated here: #0 0x72404ce554 (/system/lib64/libclang_rt.hwasan-aarch64-android.so+0xd554) #1 0x7240115654 (/apex/com.android.runtime/lib64/bionic/libc.so+0x43654) #2 0x7240450ac8 (/system/lib64/vndk-sp-R/libcutils.so+0x8ac8) [...] hwasan_dev_note_heap_rb_distance: 1 1023 hwasan_dev_note_num_matching_addrs: 0 hwasan_dev_note_num_matching_addrs_4b: 0 Thread: T0 0x006a00002000 stack: [0x007fc1064000,0x007fc1864000) sz: 8388608 tls: [0x00737702ffc0,0x007377033000) Memory tags around the buggy address (one tag corresponds to 16 bytes): 0x006f33ae1f80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1f90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1fa0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =>0x006f33ae2000: 08 00 08 00 [83] 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Tags for short granules around the buggy address (one tag corresponds to 16 bytes): 0x006f33ae1ff0: .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. =>0x006f33ae2000: 72 .. d0 .. [..] .. .. .. .. .. .. .. .. .. .. .. 0x006f33ae2010: .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. See https://clang.llvm.org/docs/HardwareAssistedAddressSanitizerDesign.html#short-granules for a description of short granule tags Registers where the failure occurred (pc 0x00623ae2a9cc): x0 0000007fc18623ec x1 5b0000433ae20045 x2 0000000000000013 x3 ffffffffffffffff x4 ffffffffffffffff x5 0000007fc1861da3 x6 6f7420676e696f47 x7 45522061206f6420 x8 0000000000000000 x9 0200006b00000000 x10 00000007fc18623f x11 5b0000433ae20040 x12 6f64206f7420676e x13 0a44414552206120 x14 0000000000000010 x15 ffffffffffffffff x16 000000737169ac94 x17 0000000000000007 x18 0000007377bd8000 x19 0000007fc1862498 x20 0200006b00000000 x21 0000007fc18624a8 x22 0000000000000001 x23 0000000000000000 x24 0000000000000000 x25 0000000000000000 x26 0000000000000000 x27 0000000000000000 x28 0000000000000000 x29 0000007fc1862410 x30 000000623ae2a9d0 sp 0000007fc18623d0 SUMMARY: HWAddressSanitizer: tag-mismatch (/system/lib64/vndk-sp-R/libcutils.so+0x8c68) [ … regular crash dump follows …]
Ceci est très similaire à un rapport AddressSanitizer . Contrairement à ceux-là, presque tous les bogues HWASan sont des « tag-mismatch », c'est-à-dire un accès mémoire où une balise de pointeur ne correspond pas à la balise mémoire correspondante. Cela pourrait être l'un des
- accès hors limites sur la pile ou le tas
- utiliser après gratuité sur le tas
- utiliser après retour sur la pile
Sections
Une explication de chacune des sections du rapport HWASan est ci-dessous :
Erreur d'accès
Contient des informations sur le mauvais accès à la mémoire, notamment :
- Type d'accès ("LECTURE" ou "ÉCRITURE")
- Taille d'accès (combien d'octets ont été tentés d'accéder)
- Numéro de thread de l'accès
- Pointeur et balises mémoire (pour le débogage avancé)
Accéder à la trace de la pile
Trace de pile du mauvais accès mémoire. Voir la section Symbolisation pour symboliser.
Cause
La cause potentielle du mauvais accès. S'il y a plusieurs candidats, ils sont classés par ordre de probabilité décroissante. Précède les informations détaillées sur la cause potentielle. HWASan peut diagnostiquer les causes suivantes :
- utilisation après libération
- stack tag-mismatch : cela peut être une utilisation de la pile après le retour / une utilisation après la portée, ou hors limites
- débordement de tampon de tas
- débordement global
Informations sur la mémoire
Décrit ce que HWASan sait de la mémoire à laquelle il accède et peut différer en fonction du type de bogue.
Type de bogue | Cause | Format du rapport |
---|---|---|
incompatibilité de balises | utilisation après libération | <address> is located N bytes inside of M-byte region [<start>, <end>) freed by thread T0 here: |
débordement de tampon de tas | Notez qu'il peut également s'agir d'un dépassement inférieur.<address> is located N bytes to the right of M-byte region [<start>, <end>) allocated here: | |
incompatibilité de balise de pile | Les rapports de pile ne font pas de différence entre les bogues de débordement/sous-débordement et les bogues d'utilisation après retour. De plus, pour trouver l’allocation de pile qui est à l’origine de l’erreur, une étape de symbolisation hors ligne est nécessaire. Consultez la section Comprendre les rapports de pile ci-dessous. | |
sans invalide | utilisation après libération | Il s'agit d'un double bug gratuit. Si cela se produit à l’arrêt du processus, cela peut signifier une violation ODR .<address> is located N bytes inside of M-byte region [<start>, <end>) freed by thread T0 here: |
je ne peux pas décrire l'adresse | Soit une libération sauvage (libre de la mémoire qui n'avait pas été allouée auparavant), soit une double libération après que la mémoire allouée ait été expulsée du tampon libre de HWASan. | |
0x… est la mémoire fantôme HWAsan. | Il s’agit définitivement d’une gratuité sauvage, car l’application tentait de libérer de la mémoire interne à HWASan. |
Trace de pile de désallocation
Trace de pile de l'endroit où la mémoire a été libérée. Présent uniquement pour les bogues utilisés après la libération ou les bogues non valides. Voir la section Symbolisation pour symboliser.
Trace de la pile d'allocation
Trace de pile de l'endroit où la mémoire a été allouée. Voir la section Symbolisation pour symboliser.
Informations de débogage avancées
Le rapport HWASan contient également des informations de débogage avancées, notamment (dans l'ordre) :
- La liste des discussions en cours
- La liste des discussions en cours
- La valeur des balises mémoire proches de la mémoire défaillante
- Le dump des registres au point d'accès à la mémoire
Vidage des balises mémoire
Le vidage mémoire de la balise peut être utilisé pour rechercher des allocations de mémoire à proximité avec la même balise que la balise de pointeur. Ceux-ci pourraient indiquer un accès hors limites avec un décalage important. Une balise correspond à 16 octets de mémoire ; la balise de pointeur correspond aux 8 premiers bits de l'adresse. Le dump mémoire des balises peut donner des indices, par exemple ce qui suit est un débordement de tampon vers la droite :
tags: ad/5c (ptr/mem) [...] Memory tags around the buggy address (one tag corresponds to 16 bytes): 0x006f33ae1ff0: 0e 0e 0e 57 20 20 20 20 20 2e 5e 5e 5e 5e 5e b5 =>0x006f33ae2000: f6 f6 f6 f6 f6 4c ad ad ad ad ad ad [5c] 5c 5c 5c 0x006f33ae2010: 5c 04 2e 2e 2e 2e 2e 2f 66 66 66 66 66 80 6a 6a Tags for short granules around the buggy address (one tag corresponds to 16 bytes): 0x006f33ae1ff0: ab 52 eb .. .. .. .. .. .. .. .. .. .. .. .. .. =>0x006f33ae2000: .. .. .. .. .. .. .. .. .. .. .. .. [..] .. .. .. 0x006f33ae2010: .. 5c .. .. .. .. .. .. .. .. .. .. .. .. .. ..(notez l'exécution de 6 × 16 = 96 octets de balises « ad » à gauche qui correspondent à la balise de pointeur).
Si la taille d'une allocation n'est pas un multiple de 16, le reste de la taille sera stocké sous forme de balise mémoire et la balise sera stockée sous forme de balise granule courte . Dans l'exemple ci-dessus, juste après l'annonce taguée avec allocation en gras, nous avons une allocation de 5 × 16 + 4 = 84 octets de la balise 5c.
Une balise mémoire nulle (ex. tags: ad/ 00 (ptr/mem)
) indique généralement un bug d'utilisation de la pile après retour.
Registre de vidage
Le vidage du registre dans les rapports HWASan correspond à l'instruction réelle qui a effectué l'accès mémoire non valide. Il est suivi d'un autre vidage de registre du gestionnaire de signal Android habituel - ignorez le second , il est effectué lorsque HWASan a appelé abort() et n'est pas pertinent pour le bogue.
Symbolisation
Pour obtenir les noms de fonctions et les numéros de ligne dans les traces de pile (et obtenir les noms de variables pour les bogues d'utilisation après portée), une étape de symbolisation hors ligne est nécessaire.
Première configuration : installez llvm-symbolizer
Pour symboliser, votre système doit avoir llvm-symbolizer installé et accessible depuis $PATH. Sur Debian, vous pouvez l'installer en utilisant sudo apt install llvm
.
Obtenir des fichiers de symboles
Pour la symbolisation, nous avons besoin de binaires non supprimés contenant des symboles. L'endroit où ils peuvent être trouvés dépend du type de construction :
Pour les versions locales , les fichiers de symboles peuvent être trouvés dans out/target/product/<product>/symbols/
.
Pour les builds AOSP (par exemple flashés depuis Flashstation ), les builds peuvent être trouvés sur Android CI . Dans les "Artefacts" de la build, il y aura un fichier `${PRODUCT}-symbols-${BUILDID}.zip`.
Pour les versions internes de votre organisation, consultez la documentation de votre organisation pour obtenir de l'aide pour obtenir des fichiers de symboles.
Symboliser
hwasan_symbolize –-symbols <DECOMPRESSED_DIR>/out/target/product/*/symbols < crash
Comprendre les rapports de pile
Pour les bogues qui surviennent avec les variables de pile, le rapport HWASan contiendra des détails comme celui-ci :
Cause: stack tag-mismatch Address 0x007d4d251e80 is located in stack of thread T64 Thread: T64 0x0074000b2000 stack: [0x007d4d14c000,0x007d4d255cb0) sz: 1088688 tls: [0x007d4d255fc0,0x007d4d259000) Previously allocated frames: record_addr:0x7df7300c98 record:0x51ef007df3f70fb0 (/apex/com.android.art/lib64/libart.so+0x570fb0) record_addr:0x7df7300c90 record:0x5200007df3cdab74 (/apex/com.android.art/lib64/libart.so+0x2dab74) [...]
Pour permettre de comprendre les bogues de pile, HWASan garde une trace des trames de pile qui se sont produites dans le passé. Actuellement, HWASan ne transforme pas cela en contenu compréhensible par l'homme dans le rapport de bug et nécessite une étape de symbolisation supplémentaire.
Violations du RLL
Certains bogues d'utilisation après libération signalés par HWASan peuvent également indiquer une violation de la règle ODR (One Definition Rule). Une violation ODR se produit lorsque la même variable est définie plusieurs fois dans le même programme. Cela signifie également que la variable est détruite plusieurs fois, ce qui peut entraîner une erreur d'utilisation après libération.
Après la symbolisation, les violations ODR affichent une utilisation après libération avec __cxa_finalize
, à la fois sur la pile d'accès non valide et sur la pile « libérée ici ». La pile "précédemment allouée ici" contient __dl__ZN6soinfo17call_constructorsEv
et doit pointer vers l'emplacement de votre programme qui définit la variable située plus haut dans la pile.
L'une des raisons pour lesquelles l'ODR peut être violé est l'utilisation de bibliothèques statiques. Si une bibliothèque statique qui définit un global C++ est liée à plusieurs bibliothèques ou exécutables partagés, plusieurs définitions du même symbole peuvent finir par exister dans le même espace d'adressage, ce qui provoquera une erreur ODR.
Dépannage
"HWAddressSanitizer ne peut pas décrire l'adresse plus en détail."
Parfois, HWASan peut manquer d’espace pour obtenir des informations sur les allocations de mémoire passées. Dans ce cas, le rapport ne contiendra qu'une seule trace de pile pour l'accès immédiat à la mémoire, suivie d'une note :
HWAddressSanitizer can not describe address in more detail.
Dans certains cas, ce problème peut être résolu en exécutant le test plusieurs fois. Une autre option consiste à augmenter la taille de l’historique HWASan. Cela peut être fait globalement dans build/soong/cc/sanitize.go
(recherchez hwasanGlobalOptions
) ou dans votre environnement de processus (essayez adb shell echo $HWASAN_OPTIONS
pour voir les paramètres actuels).
Cela peut également se produire si la mémoire accédée n'est pas mappée ou allouée par un allocateur non compatible HWASan. Dans ce cas, la balise mem
répertoriée dans l’en-tête du crash sera généralement 00
. Si vous avez accès à la pierre tombale complète, il peut être utile de consulter le dump des cartes mémoire pour savoir à quel mappage (le cas échéant) appartient l'adresse.
"bug imbriqué dans le même fil de discussion"
Cela signifie qu'il y a eu un bug lors de la génération du rapport de crash HWASan. Cela est généralement dû à un bug dans le runtime HWASan, veuillez signaler un bug et fournir des instructions sur la façon de reproduire le problème si possible.