Kdump - Analyse - Gaëtan Trellu
Analyse d'un kernel (crash, core) dump
Analyse d'un kernel (crash, core) dump
Introduction...
kernel_link est lien symbolique, il est créé à partir de la valeur DEBUG_KERNEL définie dans le fichier de configuration /...
crash 6.0.6
Copyright (C) 2002-2012 Red Hat, Inc.
Copyright (C) 2004, 2005, 2006 IBM Corporation
Copyright (C) 1999-2006 H...
Le nombre de processus au moment du crash
La version du noyau utilisé
etc...
La première interprétation des informations s...
PID: 2655
TASK: ffff88007b0b8cc0 CPU: 0
COMMAND: "insmod"
#0 [ffff88007a0c9d60] machine_kexec at ffffffff810363e4
#1 [ffff...
Il est possible de traduire l'adresse virtuelle ffffffff8100b182 par system_call_fastpath+22, pour faire cela la commande ...
Cette fonction regroupe des instructions d'assembleur pour des processeurs de type x86_64.
La lettre q présente dans les i...
PID: 2655
TASK: ffff88007b0b8cc0 CPU: 0
COMMAND: "insmod"
ARG: insmod panic.ko
ENV: TERM=xterm
SHELL=/bin/bash
SSH_CLIENT=...
MODULE
NAME
ffffffffa0005500
ffffffffa000ba40
ffffffffa00113c0
ffffffffa0017940
ffffffffa001c4a0
ffffffffa0020a60
ffffffff...
Prochain SlideShare
Chargement dans…5
×

Analyse d'un kernel (crash, core) dump

722 vues

Publié le

Kdump est une fonctionnalité du noyau Linux permettant de prendre un dump (une empreinte mémoire) lors d'un crash du système d'exploitation. Cette fonctionnalité permet d'analyser après coup ce qui s'est passé sur le serveur au moment du crash et quel a été le processus engendrant ce crash.

Après le crash d'un serveur, l'administrateur système que vous êtes espère de tout son être qu'un crashdump soit disponible dans le répertoire /var/crash/ (si tel est la destination choisie)

Publié dans : Technologie
0 commentaire
0 j’aime
Statistiques
Remarques
  • Soyez le premier à commenter

  • Soyez le premier à aimer ceci

Aucun téléchargement
Vues
Nombre de vues
722
Sur SlideShare
0
Issues des intégrations
0
Intégrations
39
Actions
Partages
0
Téléchargements
9
Commentaires
0
J’aime
0
Intégrations 0
Aucune incorporation

Aucune remarque pour cette diapositive

Analyse d'un kernel (crash, core) dump

  1. 1. Kdump - Analyse - Gaëtan Trellu Analyse d'un kernel (crash, core) dump Analyse d'un kernel (crash, core) dump Introduction Pré-requis Analyse Premiers pas État de la mémoire La backtrace, un indispensable de crash Désassembler une fonction Sources Qui à fait quoi ? Conclusion Sources Introduction Après le crash d'un serveur, l'administrateur système que vous êtes espère de tout son être qu'un crashdump soit disponible dans le répertoire / var/crash/ (si tel est la destination choisie). Dans cet exemple, la cause du crash du serveur sera liée au chargement d'un module noyau. Ce dernier appellera dès son chargement la fonction du noyau Linux : panic() Configuration de Kdump Si Kdump n'est pas encore configuré sur le serveur alors je vous invite à parcourir la procédure suivante : Debian - Kdump Pré-requis La lecture d'un crashdump Linux se fait à l'aide de l'outil crash, ce dernier permet d'interpréter de manière lisible pour l'homme les données contenues dans le fichier binaire. # aptitude install crash gdb binutils Le paquet binutils est nécessaire car il contient entre autre la commande strings qui est utilisée par crash. Sans cette commande l'erreur suivante s'affichera au lancement de la commande crash : sh: 1: /usr/bin/strings: not found Analyse À lire Cette analyse est effectuée depuis une distribution Debian GNU/Linux. Le crashdump analysé provient d'un serveur exécutant une distribution Debian GNUX/Linux. Les différences avec les autres distributions sont minimes. Dans le répertoire /var/crash/ doit se trouver un répertoire nommé de la date du crash sous la forme suivante (YYYYMMDDHHMM). Ce répertoire contient deux choses (sous Debian GNU/Linux) : lrwxrwxrwx 1 root root 55 Jul 22 19:36 kernel_link -> /usr/lib/debug/lib/modules/2.6.32-amd64/vmlinux -r-------- 1 root root 2050769968 Jul 22 19:47 vmcore.201307221946
  2. 2. kernel_link est lien symbolique, il est créé à partir de la valeur DEBUG_KERNEL définie dans le fichier de configuration /etc/default/kdum p-tools. Premiers pas En fonction de la taille du crashdump il est possible que crash soit un peu long rendre la main, c'est normal. # crash kernel_link vmcore.201307221946 Résultat :
  3. 3. crash 6.0.6 Copyright (C) 2002-2012 Red Hat, Inc. Copyright (C) 2004, 2005, 2006 IBM Corporation Copyright (C) 1999-2006 Hewlett-Packard Co Copyright (C) 2005, 2006 Fujitsu Limited Copyright (C) 2006, 2007 VA Linux Systems Japan K.K. Copyright (C) 2005 NEC Corporation Copyright (C) 1999, 2002, 2007 Silicon Graphics, Inc. Copyright (C) 1999, 2000, 2001, 2002 Mission Critical Linux, Inc. This program is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Enter "help copying" to see the conditions. This program has absolutely no warranty. Enter "help warranty" for details. GNU gdb (GDB) 7.3.1 Copyright (C) 2011 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-unknown-linux-gnu"... KERNEL: kernel_link DUMPFILE: vmcore.201307221946 CPUS: 1 DATE: Mon Jul 22 19:45:42 2013 UPTIME: 00:09:40 LOAD AVERAGE: 0.01, 0.02, 0.00 TASKS: 64 NODENAME: kernel-debug RELEASE: 2.6.32-amd64 VERSION: #1 SMP Mon Jul 8 15:25:50 EDT 2013 MACHINE: x86_64 (1995 Mhz) MEMORY: 2 GB PANIC: "[ 580.890926] Kernel panic - not syncing: Panic function called, don't be worried the system will be down !" PID: 2655 COMMAND: "insmod" TASK: ffff88007b0b8cc0 [THREAD_INFO: ffff88007a0c8000] CPU: 0 STATE: TASK_RUNNING (PANIC) Par défaut crash décide d'afficher les "méta-données" du crashdump ainsi que des copyrights, pour passer outre toutes ces informations il existe le paramètre -s à positionner juste avant kernel_link. Les premières informations fournies sont les suivantes : Le nombre de CPU La mémoire vive totale La date exacte du crash La charge du serveur au moment du crash
  4. 4. Le nombre de processus au moment du crash La version du noyau utilisé etc... La première interprétation des informations serait la suivante (Cluedo style ): Homicide Le décès eu lieu le 22 juillet 2013 à 19h45, la charge présente sur Mr kernel_debug était moindre. Seuls 64 processus étaient en cours d'exécution au moment du drame. Le sujet est un serveur de type 1 processeur 64Bits cadencé à 2Ghz, doté de 2Go de mémoire, ses origines remontent à l'an 2.6. 32. Le coupable, un jeune processus nommé insmod connu de nos services sous le PID 2655. Il causa le décès du sujet par Kernel panic et le coup mortel fut exécuté dans le CPU 0. Le mobile du crime : "Panic function called, don't be worried the system will be down !" Les informations indiquées permettent déjà d'avoir une idée de ce qui s'est passé sur le serveur, un kernel panic. État de la mémoire Il est intéressant de connaître l'état de la mémoire au moment du crash, savoir par exemple si l' OOM killer est passé faire le ménage... crash> kmem -i Résultat : PAGES TOTAL MEM FREE USED SHARED BUFFERS CACHED SLAB TOTAL SWAP SWAP USED SWAP FREE TOTAL 474877 437169 37708 6007 4375 17116 9631 0 0 0 PERCENTAGE 1.8 GB 1.7 GB 92% 147.3 MB 7% 23.5 MB 1% 17.1 MB 0% 66.9 MB 3% 37.6 MB 2% 0 0 100% 0 0% ---TOTAL TOTAL TOTAL TOTAL TOTAL TOTAL ---of TOTAL of TOTAL of of of of of of MEM MEM MEM MEM MEM MEM SWAP SWAP Dans le cas présent la consommation mémoire du serveur au moment du crash n'est pas la raison du kernel panic, il reste 92% de la mémoire disponible. Il est donc peut probable que la piste d'un Out Of Memory soit à suivre. La backtrace, un indispensable de crash La commande bt (backtrace) de l'outil crash est un must dans l'analyse de crashdump. Indispensable mais pas obligatoire (non ce n'est pas une contradiction ), il est possible de passer par les commandes log et runq pour obtenir à peu de chose près les mêmes informations. bt permet d'obtenir de plus amples informations sur le processus responsable du crash du serveur. crash> bt Résultat :
  5. 5. PID: 2655 TASK: ffff88007b0b8cc0 CPU: 0 COMMAND: "insmod" #0 [ffff88007a0c9d60] machine_kexec at ffffffff810363e4 #1 [ffff88007a0c9dd0] crash_kexec at ffffffff810e68e2 #2 [ffff88007a0c9ea0] panic at ffffffff8154d0f3 #3 [ffff88007a0c9f10] init_module at ffffffffa018b025 [panic] #4 [ffff88007a0c9f20] do_one_initcall at ffffffff8100204c #5 [ffff88007a0c9f50] sys_init_module at ffffffff810db4c6 #6 [ffff88007a0c9f80] system_call_fastpath at ffffffff8100b182 RIP: 00007f31d21fa14a RSP: 00007fffb9a1b1e8 RFLAGS: 00010206 RAX: 00000000000000af RBX: ffffffff8100b182 RCX: 00007f31d21f648a RDX: 00007f31d24b9f88 RSI: 000000000004b6ce RDI: 00007f31d288a000 RBP: 00007f31d2fbc2a0 R8: 0000000000000004 R9: 0000000000000000 R10: 00007f31d21f648a R11: 0000000000000206 R12: 0000000000000000 R13: 00007f31d2fbb090 R14: 00007f31d24b9f88 R15: 00007f31d2fbc1a0 ORIG_RAX: 00000000000000af CS: 0033 SS: 002b On récupère certaines informations déjà obtenues plus haut, comme par exemple : Le PID (2655) L'ID du CPU qui exécutait le processus (0) La commande exécutée (insmod) Mais le plus intéressant est que la fonction causant l'exception ainsi que le RIP sont indiqués ! #6 [ffff88007a0c9f80] system_call_fastpath at ffffffff8100b182 RIP: 00007f31d21fa14a RIP est un registre du processeur. Il contient l'adresse mémoire de l'instruction du programme en cours d'exécution. Exemple : Le programme panicdump.c appelle plusieurs fonctions (c'est un exemple farfelu) : open() read() close() Si le programme panicdump.c est la cause du crash alors l'une des fonctions citées ci-dessus sera certainement dans le registre RIP RIP / EIP En fonction de l'architecture CPU les registres peuvent se nommer différemment et leur nombre peut varier. x86 = Les registres se nomment E(XX) et non R(XX), exemple : EIP et non RIP x86_64 = Tous les registres se nomment R(XX), il y en a 8 de plus qu'en 32Bits Lien à consulter pour de plus amples informations : http://docs.oracle.com/cd/E19205-01/820-4220/ Au final ce que la backtrace nous apprend c'est que la fonction machine_kexec() a été appelée par la fonction crash_kernel() qui fut appelée par la fonction panic() elle même appelée par la fonction init_module() appelée par la fonction do_one_initcall() qui à son tour fut appelée par sys_init_module() finalement appelée par system_call_fastpath() qui est la fonction qui a causé le crash du serveur. Toujours avec nous ? La valeur ffffffff8100b182 située à côté de la fonction system_call_fastpath() est un offset, cet offset indique l'endroit dans la fonction qui a posé problème. Désassembler une fonction Connaître la fonction qui a causé le problème c'est utile certes mais qu'a t-elle fait pour causer un appel de la fonction panic() ? La commande dis permet de désassembler une fonction, en l'occurrence la fonction system_call_fastpath() ainsi que son offset. La fonction system_call_fastpath() peut aussi être appelée symbole.
  6. 6. Il est possible de traduire l'adresse virtuelle ffffffff8100b182 par system_call_fastpath+22, pour faire cela la commande sym sera utilisée. crash> sym ffffffff8100b182 Résultat : ffffffff8100b182 (t) system_call_fastpath+22 /usr/src/linux-2.6.32/arch/x86/kernel/entry_64.S: 505 L'option -r de dis permet de reverser une fonction, l'option -l permet d'obtenir plus de lisibilité. Exemple : crash> dis -lr ffffffff8100b182 Ou : crash> dis -lr system_call_fastpath+22 Résultat : /usr/src/linux-2.6.32/arch/x86/kernel/entry_64.S: 501 0xffffffff8100b16c <system_call_fastpath>: cmp /usr/src/linux-2.6.32/arch/x86/kernel/entry_64.S: 502 0xffffffff8100b172 <system_call_fastpath+6>: ja /usr/src/linux-2.6.32/arch/x86/kernel/entry_64.S: 503 0xffffffff8100b178 <system_call_fastpath+12>: mov /usr/src/linux-2.6.32/arch/x86/kernel/entry_64.S: 504 0xffffffff8100b17b <system_call_fastpath+15>: callq *-0x7ea96ba0(,%rax,8) /usr/src/linux-2.6.32/arch/x86/kernel/entry_64.S: 505 0xffffffff8100b182 <system_call_fastpath+22>: mov $0x1fe,%rax 0xffffffff8100b262 %r10,%rcx %rax,0x20(%rsp) Le désassemblage nous indique que la fonction system_call_fastpath()+22 a essayé de copier le contenu du registre RSP dans le registre RAX, c'est cette instruction qui a causé une exception. Sources Le code source de cette fonction se trouve dans le fichier /usr/src/linux-2.6.32/arch/x86/kernel/entry_64.S arch/x86/kernel/entry_64.S system_call_fastpath: cmpq $__NR_syscall_max,%rax ja badsys movq %r10,%rcx call *sys_call_table(,%rax,8) movq %rax,RAX-ARGOFFSET(%rsp) # XXX: rip relative
  7. 7. Cette fonction regroupe des instructions d'assembleur pour des processeurs de type x86_64. La lettre q présente dans les instructions cmpq et movq sont typiques des processeurs x86_64. Qui à fait quoi ? Il peut être parfois intéressant de savoir comment le processus a été exécuté, la commande ps propose deux options qui permettent de connaître l'arborescence père et l’arborescence fils (si cette dernière existe). 1. -p : affiche l'arborescence père 2. -c : affiche l'arborescence fils Dans le cas suivant, le processus 2655 sera passé au peigne fin. crash> ps -p 2655 Résultat : PID: 0 TASK: ffffffff81875020 CPU: 0 COMMAND: "swapper" PID: 1 TASK: ffff88007eff4040 CPU: 0 COMMAND: "init" PID: 1968 TASK: ffff88007a87d1c0 CPU: 0 COMMAND: "sshd" PID: 1998 TASK: ffff88007d66c140 CPU: 0 COMMAND: "sshd" PID: 2000 TASK: ffff88007ab7c640 CPU: 0 COMMAND: "bash" PID: 2655 TASK: ffff88007b0b8cc0 CPU: 0 COMMAND: "insmod" La commande insmod a été exécutée depuis un terminal bash par un utilisateur connecté en SSH. Le processus swapper est en fait l’ordonnanceur (scheduler), il est présent autant de fois qu'il y a de cores sur le serveur. En tant qu'administrateur système vous savez certainement que la commande insmod permet de charger un module noyau or actuellement nous n'avons aucune information sur le module qui a été chargé par cette commande. Encore une fois la commande ps permet d'avoir de plus amples informations sur l'environnement qui a exécuté la commande. crash> ps -a 2655 Résultat :
  8. 8. PID: 2655 TASK: ffff88007b0b8cc0 CPU: 0 COMMAND: "insmod" ARG: insmod panic.ko ENV: TERM=xterm SHELL=/bin/bash SSH_CLIENT=88.143.117.83 48720 22 SSH_TTY=/dev/pts/0 USER=root SSH_AUTH_SOCK=/tmp/ssh-Dk4T8LiOcC/agent.1998 MAIL=/var/mail/root PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin PWD=/root/panic_module LANG=en_US.UTF-8 SHLVL=1 HOME=/root LS_OPTIONS=--color=auto LOGNAME=root SSH_CONNECTION=88.143.117.83 48720 10.13.45.7 22 _=/sbin/insmod OLDPWD=/root Les informations ci-dessous permettent de savoir que le module panic.ko est le module qui a causé le kernel panic du serveur. Le coupable est physique car il s'est connecté à un terminal depuis SSH : SSH_CLIENT=88.143.117.83 SSH_TTY=/dev/pts/0 USER=root PWD=/root/panic_module ARG: insmod panic.ko En théorie le module panic devrait être chargé, pour le vérifier la commande mod sera utilisée. crash> mod Résultat :
  9. 9. MODULE NAME ffffffffa0005500 ffffffffa000ba40 ffffffffa00113c0 ffffffffa0017940 ffffffffa001c4a0 ffffffffa0020a60 ffffffffa0027780 ffffffffa002e620 ffffffffa0045fc0 ffffffffa0057240 ffffffffa008b280 ffffffffa00af300 ffffffffa00bab60 ffffffffa00c0240 ffffffffa00d2000 ffffffffa00e3c60 ffffffffa00ec420 ffffffffa00f4760 ffffffffa010b180 ffffffffa011c640 ffffffffa0168140 ffffffffa018b100 SIZE OBJECT FILE ata_piix 24437 (not loaded) virtio 5094 (not loaded) virtio_ring 8858 (not loaded) pata_acpi 3717 (not loaded) virtio_pci 7141 (not loaded) ata_generic 3885 (not loaded) virtio_net 17578 (not loaded) virtio_blk 7501 (not loaded) jbd 83562 (not loaded) mbcache 7945 (not loaded) ext3 244318 (not loaded) i2c_core 31840 (not loaded) i2c_piix4 13136 (not loaded) soundcore 8201 (not loaded) snd 76223 (not loaded) virtio_balloon 4778 (not loaded) snd_timer 22985 (not loaded) snd_page_alloc 8710 (not loaded) snd_pcm 93468 (not loaded) snd_pcsp 8842 (not loaded) ipv6 340294 (not loaded) panic 1004 (not loaded) [CONFIG_KALLSYMS] [CONFIG_KALLSYMS] [CONFIG_KALLSYMS] [CONFIG_KALLSYMS] [CONFIG_KALLSYMS] [CONFIG_KALLSYMS] [CONFIG_KALLSYMS] [CONFIG_KALLSYMS] [CONFIG_KALLSYMS] [CONFIG_KALLSYMS] [CONFIG_KALLSYMS] [CONFIG_KALLSYMS] [CONFIG_KALLSYMS] [CONFIG_KALLSYMS] [CONFIG_KALLSYMS] [CONFIG_KALLSYMS] [CONFIG_KALLSYMS] [CONFIG_KALLSYMS] [CONFIG_KALLSYMS] [CONFIG_KALLSYMS] [CONFIG_KALLSYMS] [CONFIG_KALLSYMS] Conclusion Dans la plupart des cas si le crashdump est lisible alors la source du crash du serveur pourra être identifiée. Debugger un crashdump n'est pas une chose facile, plusieurs paramètres peuvent entrer en cause. Si par exemple les sources d'un programme ne sont pas disponibles alors la difficulté sera accentuée. La commande crash permet de faire énormément de choses avec un crashdump, dans cette procédure je n'ai utilisé que quelques commandes mais sachez que la commande crash regorge de commandes. ps log bt -f runq foreach bt -f task Bref, la commande help listera toutes les commandes disponibles. Sources Le module panic.ko utilisé pour cette procédure http://www.dedoimedo.com/computers/crash.html http://magazine.redhat.com/2007/08/15/a-quick-overview-of-linux-kernel-crash-dump-analysis/ http://people.redhat.com/anderson/crash_whitepaper/

×