Lorsque l'outil HWASan détecte un bug de mémoire, le processus est arrêté avec abort(), et un rapport est imprimé dans stderr et logcat. Comme tous les plantages natifs sur Android, les erreurs HWASan se trouvent sous /data/tombstones.
Exemple de rapport
Par rapport aux plantages natifs classiques, HWASan contient des informations supplémentaires dans le champ Abort message (Message d'abandon) en haut de la tombe. Voici un exemple de plantage basé sur le tas de mémoire. Pour les bugs de pile, consultez la note concernant les sections spécifiques à la pile.
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 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 …]
Cela ressemble à un rapport AddressSanitizer. Contrairement à ces derniers, la quasi-totalité des bugs HWASan sont des erreurs de non-concordance des tags, c'est-à-dire un accès mémoire où un tag de pointeur ne correspond pas au tag de mémoire correspondant. Il peut s'agir de l'un des éléments suivants :
- Accès hors limites sur la pile ou le tas de mémoire
- Erreur "use-after-free" sur le tas de mémoire
- Erreur "use-after-return" sur la pile
Sections
Voici une explication de chacune des sections du rapport HWASan.
Erreur d'accès
Contient des informations sur l'accès mémoire incorrect, y compris :
- Type d'accès (
READouWRITE) - Taille de l'accès (nombre d'octets auxquels il a été tenté d'accéder)
- Numéro de thread de l'accès
- Tags de pointeur et de mémoire (pour le débogage avancé)
Trace de la pile d'accès
Trace de la pile de l'accès mémoire incorrect. Consultez Symbolisation pour symboliser.
Cause
Cause potentielle de l'accès incorrect. S'il existe plusieurs candidats, ils sont listé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 de la mémoire
- Non-concordance des tags de pile, qui peut être une utilisation de la pile après le retour, une utilisation de la pile après la portée ou hors limites
- Dépassement de la mémoire tampon du tas de mémoire
- Dépassement global
Informations sur la mémoire
Décrit ce que HWASan sait de la mémoire à laquelle il accède et peut varier en fonction du type de bug :
| Type de bug | Cause | Format du rapport |
|---|---|---|
| Non-concordance des tags | Utilisation après libération de la mémoire | Utilisez ce format de rapport :<address> is located N bytes inside of M-byte region [<start>, <end>) freed by thread T0 here: |
| Dépassement de la mémoire tampon du tas de mémoire | Notez qu'il peut également s'agir d'un dépassement négatif.<address> is located N bytes to the right of M-byte region [<start>, <end>) allocated here: |
|
| Non-concordance des tags de pile | Les rapports de pile ne font pas la distinction entre les bugs de dépassement positif ou négatif et les bugs "use-after-return". De plus, pour trouver l'allocation de pile qui est à l'origine de l'erreur, une étape de symbolisation hors connexion est requise. Consultez Comprendre les rapports de pile. | |
| Libération non valide | Utilisation après libération de la mémoire | Bug de libération double. Si cela se produit lors de l'arrêt du processus, cela peut indiquer une
violation de la règle de définition unique.
<address> is located N bytes inside of M-byte region [<start>, <end>) freed by thread T0 here: |
| Impossible de décrire l'adresse | Soit une libération aléatoire (libération de mémoire qui n'avait pas été allouée auparavant), soit une libération double après que la mémoire allouée a été supprimée de la mémoire tampon libre de HWASan. | |
| 0x... est la mémoire fantôme HWAsan | Libération aléatoire, car l'application tentait de libérer de la mémoire interne à HWASan. |
Trace de la pile de désallocation
Trace de la pile de l'endroit où la mémoire a été désallouée. Présent uniquement pour les bugs "use-after-free" ou "invalid-free". Consultez Symbolisation pour symboliser.
Trace de la pile d'allocation
Trace de la pile de l'endroit où la mémoire a été allouée. Consultez Symbolisation pour symboliser.
Informations de débogage avancées
Le rapport HWASan contient également des informations de débogage avancées, y compris (dans l'ordre) :
- La liste des threads du processus
- La liste des threads du processus
- La valeur des tags de mémoire à proximité de la mémoire défaillante
- Le dump des registres au point d'accès mémoire
Dump des tags de mémoire
Vous pouvez utiliser le dump des tags de mémoire pour rechercher les allocations de mémoire à proximité avec le même tag que le tag de pointeur. Ces tags peuvent pointer vers un accès hors limites avec un grand décalage. Un tag correspond à 16 octets de mémoire. Le tag de pointeur correspond aux 8 bits supérieurs de l'adresse. Le dump des tags de mémoire peut fournir des indications. Par exemple, voici un dépassement de mémoire tampon à 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 la série de 6 × 16 = 96 octets de tags ad à gauche qui correspondent au tag de pointeur.
Si la taille d'une allocation n'est pas un multiple de 16, le reste de la taille est stocké en tant que le
tag de mémoire et le tag est stocké en tant que tag de granule
court. Dans l'exemple précédent, juste après l'allocation en gras marquée ad, nous avons une allocation de 5 × 16 + 4 = 84 octets du tag 5c.
Un tag de mémoire nul (par exemple, tags: ad/00 (ptr/mem)) indique un
bug "use-after-return".
Dump des registres
Le dump des registres dans les rapports HWASan correspond à l'instruction qui a effectué l'accès mémoire non valide. Ce dump est suivi d'un autre dump des registres provenant du gestionnaire de signaux Android standard. Ignorez le deuxième dump, car il a été effectué lorsque HWASan a appelé
abort() et n'est pas pertinent pour le bug.
Symbolisation
Pour obtenir les noms des fonctions et les numéros de ligne dans les traces de pile (et obtenir les noms des variables pour les bugs "use-after-scope"), une étape de symbolisation hors connexion est nécessaire.
Configuration initiale : installer llvm-symbolizer
Pour symboliser, votre système doit avoir llvm-symbolizer installé et accessible depuis $PATH. Sur Debian, vous pouvez l'installer à l'aide de sudo apt install llvm.
Obtenir des fichiers de symboles
Pour la symbolisation, nous avons besoin de binaires non supprimés contenant des symboles. Leur emplacement dépend du type de build :
- Pour les builds locaux, les fichiers de symboles se trouvent dans
out/target/product/<product>/symbols/. - Pour les builds AOSP (par exemple, flashés à partir d'
Android Flash Tool), les
builds se trouvent sur Android CI. Dans les artefacts du build, il existe un fichier
${PRODUCT}-symbols-${BUILDID}.zip. - Pour les builds internes de votre organisation, consultez la documentation de votre organisation pour obtenir de l'aide sur l'obtention de fichiers de symboles.
Symboliser
hwasan_symbolize --symbols <DECOMPRESSED_DIR>/out/target/product/*/symbols < crash
Comprendre les rapports de pile
Pour les bugs qui se produisent avec des variables de pile, le rapport HWASan contient 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 vous aider à comprendre les bugs de pile, HWASan suit les frames de pile passées. HWASan ne les transforme pas en contenu compréhensible par l'homme dans le rapport de bug et nécessite une étape de symbolisation supplémentaire.
Violations de la règle de définition unique
Certains bugs "use-after-free" signalés par HWASan peuvent indiquer une violation de la règle de définition unique. Une violation de la règle de définition unique 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 l'erreur "use-after-free".
Après la symbolisation, les violations de la règle de définition unique affichent une erreur "use-after-free" avec __cxa_finalize, à la fois sur la pile d'accès non valide et sur la pile freed here (libérée ici). La pile previously allocated here (précédemment allouée ici) contient __dl__ZN6soinfo17call_constructorsEv et doit pointer vers l'emplacement de votre programme qui définit la variable plus haut dans la pile.
La règle de définition unique peut être enfreinte si des bibliothèques statiques sont utilisées. Si une bibliothèque statique qui définit un C++ global est liée à plusieurs bibliothèques partagées ou exécutables, plusieurs définitions du même symbole peuvent exister dans le même espace d'adressage, ce qui provoque une erreur de règle de définition unique.
Dépannage
Cette section décrit certaines erreurs et comment les résoudre.
HWAddressSanitizer ne peut pas décrire l'adresse plus en détail
Parfois, HWASan peut manquer d'espace pour les informations sur les allocations de mémoire passées. Dans ce cas, le rapport ne contient qu'une seule trace de la pile pour l'accès mémoire immédiat, suivie d'une note :
HWAddressSanitizer can not describe address in more detail.
Dans certains cas, vous pouvez résoudre ce problème en exécutant le test plusieurs fois. Une autre option consiste à augmenter la taille de l'historique HWASan. Vous pouvez le faire globalement dans build/soong/cc/sanitize.go (recherchez hwasanGlobalOptions) ou dans votre environnement de processus (essayez adb shell echo $HWASAN_OPTIONS pour afficher les paramètres actuels).
Cette erreur peut également se produire si la mémoire à laquelle vous accédez n'est pas mappée ou allouée par un allocateur non compatible avec HWASan. Dans ce cas, le tag mem listé dans l'en-tête du plantage est généralement 00. Si vous avez accès à la tombe complète, il peut être utile de consulter le dump des cartes mémoire pour déterminer à quel mappage (le cas échéant) appartient l'adresse.
Bug imbriqué dans le même thread
Cela signifie qu'un bug s'est produit lors de la génération du rapport de plantage HWASan. Cela est généralement dû à un bug dans l'environnement d'exécution HWASan. Signalez un bug et fournissez des instructions pour reproduire le problème si possible.