Les sections suivantes incluent les types courants de plantages natifs, une analyse d'un
exemple de crash dump et une discussion
sur les tombstones. Chaque type de plantage comprend
Exemple de résultat debuggerd
avec des preuves clés mises en évidence pour faciliter
à distinguer le type spécifique de plantage.
Abandonner
Les abandons sont intéressants, car ils sont délibérés. Il existe de nombreuses
méthodes d'annulation (y compris l'appel
abort(3)
,
à l'échec d'une
assert(3)
,
à l'aide de l'un des types de journalisation d'erreurs fatales propres à Android), mais elles impliquent toutes
Appel de abort
en cours. Un appel à abort
signale l'appel
thread avec SIGABRT, donc un frame indiquant « abort » dans libc.so
et plus
Les SIGABRT sont les éléments à rechercher dans la sortie debuggerd
pour
à reconnaître ce cas.
Un message explicite d'annulation peut s'afficher. ligne. Vous devez également consulter
Résultat de logcat
pour voir ce que ce thread a consigné avant d'avoir délibérément consigné
se suicident, car contrairement à assert(3)
ou aux erreurs fatales de niveau élevé
de journalisation, abort(3)
n'accepte pas de message.
Les versions actuelles d'Android intègrent le
tgkill(2)
système d'appel, afin que leurs piles soient les plus faciles à lire, l'appel
annuler(3) tout en haut:
pid: 4637, tid: 4637, name: crasher >>> crasher <<< signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr -------- Abort message: 'some_file.c:123: some_function: assertion "false" failed' r0 00000000 r1 0000121d r2 00000006 r3 00000008 r4 0000121d r5 0000121d r6 ffb44a1c r7 0000010c r8 00000000 r9 00000000 r10 00000000 r11 00000000 ip ffb44c20 sp ffb44a08 lr eace2b0b pc eace2b16 backtrace: #00 pc 0001cb16 /system/lib/libc.so (abort+57) #01 pc 0001cd8f /system/lib/libc.so (__assert2+22) #02 pc 00001531 /system/bin/crasher (do_action+764) #03 pc 00002301 /system/bin/crasher (main+68) #04 pc 0008a809 /system/lib/libc.so (__libc_init+48) #05 pc 00001097 /system/bin/crasher (_start_main+38)
Les anciennes versions d'Android suivaient un parcours compliqué entre la version d'origine
annuler l'appel (image 4 ici) et l'envoi réel du signal (frame 0 ici).
Cela était particulièrement vrai sur
ARM 32 bits, qui ajoutait
__libc_android_abort
(image 3 ici) aux autres plates-formes
séquence de raise
/pthread_kill
/tgkill
:
pid: 1656, tid: 1656, name: crasher >>> crasher <<< signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr -------- Abort message: 'some_file.c:123: some_function: assertion "false" failed' r0 00000000 r1 00000678 r2 00000006 r3 f70b6dc8 r4 f70b6dd0 r5 f70b6d80 r6 00000002 r7 0000010c r8 ffffffed r9 00000000 sl 00000000 fp ff96ae1c ip 00000006 sp ff96ad18 lr f700ced5 pc f700dc98 cpsr 400b0010 backtrace: #00 pc 00042c98 /system/lib/libc.so (tgkill+12) #01 pc 00041ed1 /system/lib/libc.so (pthread_kill+32) #02 pc 0001bb87 /system/lib/libc.so (raise+10) #03 pc 00018cad /system/lib/libc.so (__libc_android_abort+34) #04 pc 000168e8 /system/lib/libc.so (abort+4) #05 pc 0001a78f /system/lib/libc.so (__libc_fatal+16) #06 pc 00018d35 /system/lib/libc.so (__assert2+20) #07 pc 00000f21 /system/xbin/crasher #08 pc 00016795 /system/lib/libc.so (__libc_init+44) #09 pc 00000abc /system/xbin/crasher
Vous pouvez reproduire une instance de ce type de plantage à l'aide de crasher
abort
.
Déréférencement du pointeur nul pur
Il s'agit du plantage natif classique, et bien qu'il ne s'agisse que d'un cas particulier il est utile de le mentionner séparément, car il nécessite généralement le moins réfléchi.
Dans l'exemple ci-dessous, même si la fonction
plantage se trouve dans
libc.so
, car les fonctions de chaîne n'opèrent que sur le
les pointeurs qu'ils reçoivent, vous pouvez en déduire que
strlen(3)
a été appelé avec un pointeur nul ; et ce plantage devrait aller directement
l'auteur du code appelant. Dans ce cas, le cadre n° 01 est l'appelant incorrect.
pid: 25326, tid: 25326, name: crasher >>> crasher <<< signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0 r0 00000000 r1 00000000 r2 00004c00 r3 00000000 r4 ab088071 r5 fff92b34 r6 00000002 r7 fff92b40 r8 00000000 r9 00000000 sl 00000000 fp fff92b2c ip ab08cfc4 sp fff92a08 lr ab087a93 pc efb78988 cpsr 600d0030 backtrace: #00 pc 00019988 /system/lib/libc.so (strlen+71) #01 pc 00001a8f /system/xbin/crasher (strlen_null+22) #02 pc 000017cd /system/xbin/crasher (do_action+948) #03 pc 000020d5 /system/xbin/crasher (main+100) #04 pc 000177a1 /system/lib/libc.so (__libc_init+48) #05 pc 000010e4 /system/xbin/crasher (_start+96)
Vous pouvez reproduire une instance de ce type de plantage à l'aide de crasher
strlen-NULL
.
Déréférence de pointeur nul pour une adresse inférieure
Dans de nombreux cas, l'adresse de défaut
n'est pas 0, mais un autre nombre peu élevé. Deux ou
Les adresses à trois chiffres sont très courantes, alors qu'une adresse à six chiffres
n'est probablement pas une déréférence de pointeur nul,
nécessitent un décalage de 1 Mio. Cela se produit généralement
lorsque vous avez du code qui
déréférence un pointeur nul comme s'il s'agissait d'un struct valide. Les fonctions courantes sont
fprintf(3)
(ou toute autre fonction utilisant un FICHIER*) et
readdir(3)
,
car le code ne parvient souvent pas à vérifier
fopen(3)
ou
opendir(3)
l'appel a réellement réussi en premier.
Voici un exemple de readdir
:
pid: 25405, tid: 25405, name: crasher >>> crasher <<< signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xc r0 0000000c r1 00000000 r2 00000000 r3 3d5f0000 r4 00000000 r5 0000000c r6 00000002 r7 ff8618f0 r8 00000000 r9 00000000 sl 00000000 fp ff8618dc ip edaa6834 sp ff8617a8 lr eda34a1f pc eda618f6 cpsr 600d0030 backtrace: #00 pc 000478f6 /system/lib/libc.so (pthread_mutex_lock+1) #01 pc 0001aa1b /system/lib/libc.so (readdir+10) #02 pc 00001b35 /system/xbin/crasher (readdir_null+20) #03 pc 00001815 /system/xbin/crasher (do_action+976) #04 pc 000021e5 /system/xbin/crasher (main+100) #05 pc 000177a1 /system/lib/libc.so (__libc_init+48) #06 pc 00001110 /system/xbin/crasher (_start+96)
Ici, la cause directe du plantage est
pthread_mutex_lock(3)
a tenté d'accéder à l'adresse 0xc (frame 0). Mais la première chose
pthread_mutex_lock
déréférence state
.
de l'élément pthread_mutex_t*
qui lui a été fourni. Si vous examinez
la source, vous pouvez voir que l'élément est décalé de 0 dans le struct, ce qui vous indique
que pthread_mutex_lock
a reçu le pointeur non valide 0xc. De
vous pouvez voir que readdir
a reçu ce pointeur dans le cadre 1.
qui extrait le champ mutex_
du DIR*
dont il est
données. En regardant cette structure, vous pouvez voir que mutex_
se trouve à
décaler sizeof(int) + sizeof(size_t) + sizeof(dirent*)
en
struct DIR
, qui sur un appareil 32 bits correspond à 4 + 4 + 4 = 12 = 0xc, donc
vous avez trouvé le bug: readdir
a reçu un pointeur nul par le
appelant. À ce stade, vous pouvez coller la pile
dans l'outil d'empilement pour voir
where dans logcat s'est produite.
struct DIR { int fd_; size_t available_bytes_; dirent* next_; pthread_mutex_t mutex_; dirent buff_[15]; long current_pos_; };
Dans la plupart des cas, vous pouvez ignorer cette analyse. Une défaillance suffisamment basse
signifie généralement que vous pouvez simplement ignorer n'importe quel frame libc.so
dans
et accusent directement le code d'appel. Mais pas toujours, et c'est ainsi que
vous présenterez
un cas convaincant.
Vous pouvez reproduire des instances de ce type de plantage en utilisant crasher
fprintf-NULL
ou crasher readdir-NULL
.
Échec de FORTIFY
Un échec de FORTIFY est un cas particulier d'annulation qui se produit lorsque la bibliothèque C
détecte un problème qui pourrait
entraîner une faille de sécurité. Bibliothèque C de nombreuses
fonctions fortifiées ; il prend un argument supplémentaire
qui lui indique
la taille réelle d'un tampon et vérifier lors de l'exécution si l'opération
que vous essayez d'effectuer
pour les ajustements de taille. Dans cet exemple, le code tente
en read(fd, buf, 32)
dans un tampon de 10 octets seulement
long...
pid: 25579, tid: 25579, name: crasher >>> crasher <<< signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr -------- Abort message: 'FORTIFY: read: prevented 32-byte write into 10-byte buffer' r0 00000000 r1 000063eb r2 00000006 r3 00000008 r4 ff96f350 r5 000063eb r6 000063eb r7 0000010c r8 00000000 r9 00000000 sl 00000000 fp ff96f49c ip 00000000 sp ff96f340 lr ee83ece3 pc ee86ef0c cpsr 000d0010 backtrace: #00 pc 00049f0c /system/lib/libc.so (tgkill+12) #01 pc 00019cdf /system/lib/libc.so (abort+50) #02 pc 0001e197 /system/lib/libc.so (__fortify_fatal+30) #03 pc 0001baf9 /system/lib/libc.so (__read_chk+48) #04 pc 0000165b /system/xbin/crasher (do_action+534) #05 pc 000021e5 /system/xbin/crasher (main+100) #06 pc 000177a1 /system/lib/libc.so (__libc_init+48) #07 pc 00001110 /system/xbin/crasher (_start+96)
Vous pouvez reproduire une instance de ce type de plantage à l'aide de crasher
fortify
.
Corruption de la pile détectée par -fstack-protector
L'option -fstack-protector
du compilateur insère des vérifications dans
avec des tampons sur la pile pour se protéger contre les dépassements de tampon. Cette option
est activé par défaut pour le code de plate-forme, mais pas pour les applications. Lorsque cette option est
activé, le compilateur ajoute des instructions
fonction
prologue pour écrire une valeur aléatoire juste après la dernière valeur locale de la pile.
à la fonction épilogue pour la relire
et vérifier qu'elle n'a pas été modifiée. Si
cette valeur a changé, elle a été écrasée par un dépassement de tampon, donc l'épilogue
appelle __stack_chk_fail
pour consigner un message et abandonner.
pid: 26717, tid: 26717, name: crasher >>> crasher <<< signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr -------- Abort message: 'stack corruption detected' r0 00000000 r1 0000685d r2 00000006 r3 00000008 r4 ffd516d8 r5 0000685d r6 0000685d r7 0000010c r8 00000000 r9 00000000 sl 00000000 fp ffd518bc ip 00000000 sp ffd516c8 lr ee63ece3 pc ee66ef0c cpsr 000e0010 backtrace: #00 pc 00049f0c /system/lib/libc.so (tgkill+12) #01 pc 00019cdf /system/lib/libc.so (abort+50) #02 pc 0001e07d /system/lib/libc.so (__libc_fatal+24) #03 pc 0004863f /system/lib/libc.so (__stack_chk_fail+6) #04 pc 000013ed /system/xbin/crasher (smash_stack+76) #05 pc 00001591 /system/xbin/crasher (do_action+280) #06 pc 00002219 /system/xbin/crasher (main+100) #07 pc 000177a1 /system/lib/libc.so (__libc_init+48) #08 pc 00001144 /system/xbin/crasher (_start+96)
Vous pouvez le distinguer des autres types d'abandon par la présence
__stack_chk_fail
dans la trace arrière et le message d'abandon spécifique.
Vous pouvez reproduire une instance de ce type de plantage à l'aide de crasher
smash-stack
.
Seccomp SIGSYS à partir d'un appel système non autorisé
L'API seccomp
system (en particulier seccomp-bpf) limite l'accès aux appels système. Pour plus
informations sur seccomp pour les développeurs de plates-formes, voir l'article de blog
SecComp
filtre dans Android O. Un thread qui appelle un appel système restreint
recevoir un signal SIGSYS avec
le code SYS_SECCOMP. Le numéro d'appel système sera
illustré dans la cause, ainsi que l'architecture. Il est important de noter
les numéros d'appel du système varient
d'une architecture à l'autre. Par exemple,
L'appel système de readlinkat(2)
est le numéro 305 sur x86, mais 267 sur x86-64.
Le numéro d'appel est à nouveau différent sur arm et arm64. Comme l'appel système
les nombres varient d'une architecture à l'autre, il est généralement plus facile d'utiliser la trace de la pile
pour identifier l'appel système qui a été refusé, plutôt que de rechercher
le numéro d'appel du système
dans les en-têtes.
pid: 11046, tid: 11046, name: crasher >>> crasher <<< signal 31 (SIGSYS), code 1 (SYS_SECCOMP), fault addr -------- Cause: seccomp prevented call to disallowed arm system call 99999 r0 cfda0444 r1 00000014 r2 40000000 r3 00000000 r4 00000000 r5 00000000 r6 00000000 r7 0001869f r8 00000000 r9 00000000 sl 00000000 fp fffefa58 ip fffef898 sp fffef888 lr 00401997 pc f74f3658 cpsr 600f0010 backtrace: #00 pc 00019658 /system/lib/libc.so (syscall+32) #01 pc 00001993 /system/bin/crasher (do_action+1474) #02 pc 00002699 /system/bin/crasher (main+68) #03 pc 0007c60d /system/lib/libc.so (__libc_init+48) #04 pc 000011b0 /system/bin/crasher (_start_main+72)
Vous pouvez distinguer les appels système non autorisés des autres plantages grâce à la présence
SYS_SECCOMP
sur la ligne du signal et la description sur la ligne correspondant à la cause du problème.
Vous pouvez reproduire une instance de ce type de plantage à l'aide de crasher
seccomp
.
Non-respect de la mémoire d'exécution seule (Android 10 uniquement)
Pour arm64 sous Android 10 uniquement, les segments exécutables les binaires et les bibliothèques ont été mappés en mémoire en mode exécution uniquement (non lisible) pour renforcer la protection contre les attaques par réutilisation de code. Cette mesure d’atténuation a eu une mauvaise interaction avec d’autres mesures d’atténuation et a ensuite été supprimée.
Rendre le code illisible entraîne des lectures intentionnelles et non intentionnelles dans les segments de mémoire marqués
"execute-only" pour générer une SIGSEGV
avec le code SEGV_ACCERR
. Cela pourrait
se produire suite à un bug, une faille, des données mélangées à du code (par exemple, un pool littéral),
ou l'introspection intentionnelle
de la mémoire.
Le compilateur suppose que le code et les données ne sont pas mélangés, mais des problèmes peuvent survenir à partir de
l'assemblage. Dans de nombreux cas, vous pouvez résoudre ce problème en déplaçant simplement les constantes vers un .data
.
.
Si l'introspection de code est absolument
nécessaire sur les sections de code exécutables,
mprotect(2)
doit d'abord être appelé pour indiquer que le code est lisible, puis une seconde fois pour le marquer comme illisible après la balise
est terminée.
pid: 2938, tid: 2940, name: crasher64 >>> crasher64 <<< signal 11 (SIGSEGV), code 2 (SEGV_ACCERR), fault addr 0x5f2ced24a8 Cause: execute-only (no-read) memory access error; likely due to data in .text. x0 0000000000000000 x1 0000005f2cecf21f x2 0000000000000078 x3 0000000000000053 x4 0000000000000074 x5 8000000000000000 x6 ff71646772607162 x7 00000020dcf0d16c x8 0000005f2ced24a8 x9 000000781251c55e x10 0000000000000000 x11 0000000000000000 x12 0000000000000014 x13 ffffffffffffffff x14 0000000000000002 x15 ffffffffffffffff x16 0000005f2ced52f0 x17 00000078125c0ed8 x18 0000007810e8e000 x19 00000078119fbd50 x20 00000078125d6020 x21 00000078119fbd50 x22 00000b7a00000b7a x23 00000078119fbdd8 x24 00000078119fbd50 x25 00000078119fbd50 x26 00000078119fc018 x27 00000078128ea020 x28 00000078119fc020 x29 00000078119fbcb0 sp 00000078119fba40 lr 0000005f2ced1b94 pc 0000005f2ced1ba4 backtrace: #00 pc 0000000000003ba4 /system/bin/crasher64 (do_action+2348) #01 pc 0000000000003234 /system/bin/crasher64 (thread_callback+44) #02 pc 00000000000e2044 /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+36) #03 pc 0000000000083de0 /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64)
Vous pouvez distinguer les violations de mémoire d'exécution uniquement des autres plantages en fonction de la cause.
Vous pouvez reproduire une instance de ce type de plantage à l'aide de crasher xom
.
Erreur détectée par fdsan
Le désinfectant de descripteur de fichier fdsan d'Android permet de détecter les erreurs courantes avec des descripteurs de fichier tels que comme use-after-close et double-close. Consultez le fdsan documentation pour découvrir comment déboguer (et éviter) cette catégorie d'erreurs.
pid: 32315, tid: 32315, name: crasher64 >>> crasher64 <<< signal 35 (), code -1 (SI_QUEUE), fault addr -------- Abort message: 'attempted to close file descriptor 3, expected to be unowned, actually owned by FILE* 0x7d8e413018' x0 0000000000000000 x1 0000000000007e3b x2 0000000000000023 x3 0000007fe7300bb0 x4 3033313465386437 x5 3033313465386437 x6 3033313465386437 x7 3831303331346538 x8 00000000000000f0 x9 0000000000000000 x10 0000000000000059 x11 0000000000000034 x12 0000007d8ebc3a49 x13 0000007fe730077a x14 0000007fe730077a x15 0000000000000000 x16 0000007d8ec9a7b8 x17 0000007d8ec779f0 x18 0000007d8f29c000 x19 0000000000007e3b x20 0000000000007e3b x21 0000007d8f023020 x22 0000007d8f3b58dc x23 0000000000000001 x24 0000007fe73009a0 x25 0000007fe73008e0 x26 0000007fe7300ca0 x27 0000000000000000 x28 0000000000000000 x29 0000007fe7300c90 sp 0000007fe7300860 lr 0000007d8ec2f22c pc 0000007d8ec2f250 backtrace: #00 pc 0000000000088250 /bionic/lib64/libc.so (fdsan_error(char const*, ...)+384) #01 pc 0000000000088060 /bionic/lib64/libc.so (android_fdsan_close_with_tag+632) #02 pc 00000000000887e8 /bionic/lib64/libc.so (close+16) #03 pc 000000000000379c /system/bin/crasher64 (do_action+1316) #04 pc 00000000000049c8 /system/bin/crasher64 (main+96) #05 pc 000000000008021c /bionic/lib64/libc.so (_start_main)
Vous pouvez le distinguer des autres types d'abandon par la présence
fdsan_error
dans la trace arrière et le message d'abandon spécifique.
Vous pouvez reproduire une instance
de ce type de plantage en utilisant
crasher fdsan_file
ou crasher fdsan_dir
.
Examiner les fichiers de crash dump
Si vous n'êtes pas concerné par un plantage en ce moment,
le source de la plate-forme inclut un outil de test debuggerd
appelé
un plantage en ligne. Si vous mm
dans system/core/debuggerd/
, vous :
obtenez à la fois un crasher
et un crasher64
sur votre chemin (le
la dernière vous permettant de tester les plantages 64 bits). Le plantage peut planter
de manières intéressantes basées sur les arguments
de ligne de commande que vous fournissez.
Utilisez crasher --help
pour afficher la sélection actuellement acceptée.
Pour présenter les différents éléments d'un crash dump, examinons ce exemple de crash dump:
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** Build fingerprint: 'Android/aosp_flounder/flounder:5.1.51/AOSP/enh08201009:eng/test-keys' Revision: '0' ABI: 'arm' pid: 1656, tid: 1656, name: crasher >>> crasher <<< signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr -------- Abort message: 'some_file.c:123: some_function: assertion "false" failed' r0 00000000 r1 00000678 r2 00000006 r3 f70b6dc8 r4 f70b6dd0 r5 f70b6d80 r6 00000002 r7 0000010c r8 ffffffed r9 00000000 sl 00000000 fp ff96ae1c ip 00000006 sp ff96ad18 lr f700ced5 pc f700dc98 cpsr 400b0010 backtrace: #00 pc 00042c98 /system/lib/libc.so (tgkill+12) #01 pc 00041ed1 /system/lib/libc.so (pthread_kill+32) #02 pc 0001bb87 /system/lib/libc.so (raise+10) #03 pc 00018cad /system/lib/libc.so (__libc_android_abort+34) #04 pc 000168e8 /system/lib/libc.so (abort+4) #05 pc 0001a78f /system/lib/libc.so (__libc_fatal+16) #06 pc 00018d35 /system/lib/libc.so (__assert2+20) #07 pc 00000f21 /system/xbin/crasher #08 pc 00016795 /system/lib/libc.so (__libc_init+44) #09 pc 00000abc /system/xbin/crasher Tombstone written to: /data/tombstones/tombstone_06 *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
La ligne d'astérisques avec des espaces est utile si vous effectuez une recherche dans un journal pour les plantages natifs. Chaîne "*** ***" apparaît rarement dans les journaux, au début d'un plantage natif.
Build fingerprint: 'Android/aosp_flounder/flounder:5.1.51/AOSP/enh08201009:eng/test-keys'
L'empreinte vous permet d'identifier précisément le build sur lequel le plantage s'est produit.
C'est exactement la même chose que le système ro.build.fingerprint
.
.
Revision: '0'
La révision fait référence au matériel plutôt qu'au logiciel. C'est généralement
Non utilisé, mais cela peut être utile pour vous aider à ignorer automatiquement les bugs connus
causée par un mauvais matériel. C'est exactement la même chose que
Propriété système ro.revision
.
ABI: 'arm'
L'ABI est "arm", "arm64", "x86" ou "x86-64". Il s'agit principalement
utile pour le script stack
mentionné ci-dessus, afin qu'il sache
la chaîne d'outils à utiliser.
pid: 1656, tid: 1656, name: crasher >>> crasher <<<
Cette ligne identifie le thread spécifique dans le processus qui a planté. Dans ce c'était le processus. thread principal, de sorte que l'ID du processus et l'ID du thread correspondent. Le premier nom est le nom du fil de discussion, suivi du nom entouré de >>> et <<< est le nom du processus. Pour une application, le nom du processus est généralement le nom complet du package (par exemple, com.facebook.katana), qui est utiles pour signaler des bugs ou essayer de trouver l'application dans Google Play. Le pid et tid peut également être utile pour trouver les lignes de journal pertinentes précédant le plantage.
signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------
Cette ligne vous indique quel signal (SIGABRT) a été reçu, et plus sur la façon dont il
a été reçue (SI_TKILL). Les signaux indiqués par debuggerd
sont les suivants :
SIGABRT, SIGBUS, SIGFPE, SIGILL, SIGSEGV et SIGTRAP. Les paramètres spécifiques au signal
différents selon le signal.
Abort message: 'some_file.c:123: some_function: assertion "false" failed'
Les plantages ne sont pas tous associés à une ligne de message d'abandon, contrairement aux abandons. C'est automatiquement collectées à partir de la dernière ligne de la sortie Logcat fatale pid/tid et, dans le cas d'un abandon délibéré, est susceptible de donner pourquoi le programme s’est tué tout seul.
r0 00000000 r1 00000678 r2 00000006 r3 f70b6dc8 r4 f70b6dd0 r5 f70b6d80 r6 00000002 r7 0000010c r8 ffffffed r9 00000000 sl 00000000 fp ff96ae1c ip 00000006 sp ff96ad18 lr f700ced5 pc f700dc98 cpsr 400b0010
Le vidage de registre affiche le contenu des registres du processeur au moment où le si le signal a été reçu. (Cette section varie considérablement d'une ABI à l'autre.) À quel point dépendent du plantage exact.
backtrace: #00 pc 00042c98 /system/lib/libc.so (tgkill+12) #01 pc 00041ed1 /system/lib/libc.so (pthread_kill+32) #02 pc 0001bb87 /system/lib/libc.so (raise+10) #03 pc 00018cad /system/lib/libc.so (__libc_android_abort+34) #04 pc 000168e8 /system/lib/libc.so (abort+4) #05 pc 0001a78f /system/lib/libc.so (__libc_fatal+16) #06 pc 00018d35 /system/lib/libc.so (__assert2+20) #07 pc 00000f21 /system/xbin/crasher #08 pc 00016795 /system/lib/libc.so (__libc_init+44) #09 pc 00000abc /system/xbin/crasher
La trace arrière vous indique où nous étions dans le code au moment du plantage. La
La première colonne indique le numéro de frame (correspondant au style de gdb où le frame le plus profond
est de 0). Les valeurs PC sont relatives à l'emplacement de la bibliothèque partagée
que les adresses absolues. La colonne suivante correspond au nom de la région mappée
(qui est généralement une bibliothèque
partagée ou un exécutable, mais qui ne convient peut-être pas, par exemple,
code compilé JIT). Enfin, si des symboles sont disponibles, le symbole que le PC
correspondant à cette valeur, ainsi que le décalage dans ce symbole dans
octets. Vous pouvez l'utiliser conjointement avec objdump(1)
pour trouver
l'instruction d'assembleur correspondante.
Lire les pierres tombales
Tombstone written to: /data/tombstones/tombstone_06
Indique où debuggerd
a écrit des informations supplémentaires.
debuggerd
conserve jusqu'à 10 pierres tombales tout au long de la
les numéros 00 à 09 et en écrasant
les tombstones existants si nécessaire.
La pierre tombale contient les mêmes informations que le crash dump, plus quelques
extras. Par exemple, il inclut des traces arrière pour tous les threads (et non pour
uniquement le thread qui plante), les registres à virgule flottante, les vidages de pile bruts
et des vidages de mémoire autour
des adresses dans les registres. Encore plus utile, c'est aussi
inclut une carte de mémoire complète (semblable à /proc/pid/maps
).
Voici un exemple annoté d'un plantage de processus ARM 32 bits:
memory map: (fault address prefixed with --->) --->ab15f000-ab162fff r-x 0 4000 /system/xbin/crasher (BuildId: b9527db01b5cf8f5402f899f64b9b121)
Deux points sont à noter ici. La première est que cette ligne est préfixée avec "--->". Les cartes sont plus utiles lorsque votre plantage n'est pas seulement une valeur nulle déréférencement du pointeur. Si l'adresse de défaut est petite, il s'agit probablement d'une variante d'une déréférence de pointeur nul. Sinon, regardez les cartes situées autour de la faille. adresse peut souvent vous donner un indice sur ce qui s’est passé. Quelques problèmes possibles en observant les cartes sont les suivants:
- Lit/écrit au-delà de la fin d'un bloc de mémoire.
- Lit/écrit avant le début d'un bloc de mémoire.
- Tentatives d'exécution sans code.
- À la fin d'une pile.
- Tente d'écrire dans le code (comme dans l'exemple ci-dessus).
Deuxième point à noter : les fichiers exécutables et les bibliothèques partagées
afficher le BuildId (s'il est présent) sous Android 6.0 ou version ultérieure, afin que vous puissiez voir exactement
la version de votre code qui a planté. Les binaires de la plate-forme
comprennent un ID de compilation
par défaut depuis Android 6.0 ; NDK r12 et versions ultérieures passent automatiquement
-Wl,--build-id
à l'éditeur de liens aussi.
ab163000-ab163fff r-- 3000 1000 /system/xbin/crasher ab164000-ab164fff rw- 0 1000 f6c80000-f6d7ffff rw- 0 100000 [anon:libc_malloc]
Sur Android, le tas de mémoire n'est pas nécessairement une seule région. Les segments de mémoire
être associé au libellé [anon:libc_malloc]
.
f6d82000-f6da1fff r-- 0 20000 /dev/__properties__/u:object_r:logd_prop:s0 f6da2000-f6dc1fff r-- 0 20000 /dev/__properties__/u:object_r:default_prop:s0 f6dc2000-f6de1fff r-- 0 20000 /dev/__properties__/u:object_r:logd_prop:s0 f6de2000-f6de5fff r-x 0 4000 /system/lib/libnetd_client.so (BuildId: 08020aa06ed48cf9f6971861abf06c9d) f6de6000-f6de6fff r-- 3000 1000 /system/lib/libnetd_client.so f6de7000-f6de7fff rw- 4000 1000 /system/lib/libnetd_client.so f6dec000-f6e74fff r-x 0 89000 /system/lib/libc++.so (BuildId: 8f1f2be4b37d7067d366543fafececa2) (load base 0x2000) f6e75000-f6e75fff --- 0 1000 f6e76000-f6e79fff r-- 89000 4000 /system/lib/libc++.so f6e7a000-f6e7afff rw- 8d000 1000 /system/lib/libc++.so f6e7b000-f6e7bfff rw- 0 1000 [anon:.bss] f6e7c000-f6efdfff r-x 0 82000 /system/lib/libc.so (BuildId: d189b369d1aafe11feb7014d411bb9c3) f6efe000-f6f01fff r-- 81000 4000 /system/lib/libc.so f6f02000-f6f03fff rw- 85000 2000 /system/lib/libc.so f6f04000-f6f04fff rw- 0 1000 [anon:.bss] f6f05000-f6f05fff r-- 0 1000 [anon:.bss] f6f06000-f6f0bfff rw- 0 6000 [anon:.bss] f6f0c000-f6f21fff r-x 0 16000 /system/lib/libcutils.so (BuildId: d6d68a419dadd645ca852cd339f89741) f6f22000-f6f22fff r-- 15000 1000 /system/lib/libcutils.so f6f23000-f6f23fff rw- 16000 1000 /system/lib/libcutils.so f6f24000-f6f31fff r-x 0 e000 /system/lib/liblog.so (BuildId: e4d30918d1b1028a1ba23d2ab72536fc) f6f32000-f6f32fff r-- d000 1000 /system/lib/liblog.so f6f33000-f6f33fff rw- e000 1000 /system/lib/liblog.so
En règle générale, une bibliothèque partagée a trois entrées adjacentes. L'un est lisible et
exécutable (code), l'un est en lecture seule (données en lecture seule) et l'autre est en lecture/écriture
(données modifiables). La première colonne indique les plages d'adresses utilisées pour le mappage,
Dans la deuxième colonne, indiquez les autorisations (dans le style Unix ls(1)
habituel).
la troisième colonne le décalage dans le fichier (en hexadécimal), la quatrième colonne le décalage dans le fichier (en hexadécimal), la quatrième colonne la taille
de la région (en hexadécimal) et, en cinquième, le fichier (ou un autre nom de région).
f6f34000-f6f53fff r-x 0 20000 /system/lib/libm.so (BuildId: 76ba45dcd9247e60227200976a02c69b) f6f54000-f6f54fff --- 0 1000 f6f55000-f6f55fff r-- 20000 1000 /system/lib/libm.so f6f56000-f6f56fff rw- 21000 1000 /system/lib/libm.so f6f58000-f6f58fff rw- 0 1000 f6f59000-f6f78fff r-- 0 20000 /dev/__properties__/u:object_r:default_prop:s0 f6f79000-f6f98fff r-- 0 20000 /dev/__properties__/properties_serial f6f99000-f6f99fff rw- 0 1000 [anon:linker_alloc_vector] f6f9a000-f6f9afff r-- 0 1000 [anon:atexit handlers] f6f9b000-f6fbafff r-- 0 20000 /dev/__properties__/properties_serial f6fbb000-f6fbbfff rw- 0 1000 [anon:linker_alloc_vector] f6fbc000-f6fbcfff rw- 0 1000 [anon:linker_alloc_small_objects] f6fbd000-f6fbdfff rw- 0 1000 [anon:linker_alloc_vector] f6fbe000-f6fbffff rw- 0 2000 [anon:linker_alloc] f6fc0000-f6fc0fff r-- 0 1000 [anon:linker_alloc] f6fc1000-f6fc1fff rw- 0 1000 [anon:linker_alloc_lob] f6fc2000-f6fc2fff r-- 0 1000 [anon:linker_alloc] f6fc3000-f6fc3fff rw- 0 1000 [anon:linker_alloc_vector] f6fc4000-f6fc4fff rw- 0 1000 [anon:linker_alloc_small_objects] f6fc5000-f6fc5fff rw- 0 1000 [anon:linker_alloc_vector] f6fc6000-f6fc6fff rw- 0 1000 [anon:linker_alloc_small_objects] f6fc7000-f6fc7fff rw- 0 1000 [anon:arc4random _rsx structure] f6fc8000-f6fc8fff rw- 0 1000 [anon:arc4random _rs structure] f6fc9000-f6fc9fff r-- 0 1000 [anon:atexit handlers] f6fca000-f6fcafff --- 0 1000 [anon:thread signal stack guard page]
À partir d'Android 5.0, la bibliothèque C nomme la plupart de ses régions mappées anonymes, de sorte que il y a moins de régions mystères.
f6fcb000-f6fccfff rw- 0 2000 [stack:5081]
Les régions nommées [stack:tid]
sont les piles de l'entité donnée
les threads.
f6fcd000-f702afff r-x 0 5e000 /system/bin/linker (BuildId: 84f1316198deee0591c8ac7f158f28b7) f702b000-f702cfff r-- 5d000 2000 /system/bin/linker f702d000-f702dfff rw- 5f000 1000 /system/bin/linker f702e000-f702ffff rw- 0 2000 f7030000-f7030fff r-- 0 1000 f7031000-f7032fff rw- 0 2000 ffcd7000-ffcf7fff rw- 0 21000 ffff0000-ffff0fff r-x 0 1000 [vectors]
L'affichage de [vector]
ou de [vdso]
dépend de la
de l'architecture. ARM utilise [vector]
, tandis que toutes les autres architectures utilisent
[vdso]