Considérez la trace de pile de vidage du noyau Linux suivante, vous pouvez déclencher une panique à partir du code source du noyau en appelant panic("debugging a linux kernel panic");
:
[<001360ac>] (unwind_backtrace+0x0/0xf8) from [<00147b7c>] (warn_slowpath_common+0x50/0x60)
[<00147b7c>] (warn_slowpath_common+0x50/0x60) from [<00147c40>] (warn_slowpath_null+0x1c/0x24)
[<00147c40>] (warn_slowpath_null+0x1c/0x24) from [<0014de44>] (local_bh_enable_ip+0xa0/0xac)
[<0014de44>] (local_bh_enable_ip+0xa0/0xac) from [<0019594c>] (bdi_register+0xec/0x150)
unwind_backtrace+0x0/0xf8
ce que le +0x0/0xf8
signifie?unwind_backtrace+0x0/0xf8
?C'est juste une trace ordinaire, ces fonctions sont appelées dans l'ordre inverse (la première appelée a été appelée par la précédente et ainsi de suite):
unwind_backtrace+0x0/0xf8
warn_slowpath_common+0x50/0x60
warn_slowpath_null+0x1c/0x24
ocal_bh_enable_ip+0xa0/0xac
bdi_register+0xec/0x150
Le bdi_register+0xec/0x150
Est le symbole + l'offset/la longueur, il y a plus d'informations à ce sujet dans nderstanding a Kernel Oops et comment vous pouvez déboguer un kernel oops. Il y a aussi cet excellent tutoriel sur Débogage du noya
Remarque: comme suggéré ci-dessous par Eugene, vous voudrez peut-être essayer addr2line d'abord, il a toujours besoin d'une image avec des symboles de débogage, par exemple
addr2line -e vmlinux_with_debug_info 0019594c(+offset)
Voici 2 alternatives pour addr2line
. En supposant que vous disposez de la chaîne d'outils de la cible appropriée, vous pouvez effectuer l'une des opérations suivantes:
Utilisez objdump
:
localisez votre vmlinux
ou le fichier .ko
sous le répertoire racine du noyau, puis démontez le fichier objet:
objdump -dS vmlinux > /tmp/kernel.s
Ouvrez le fichier d'assemblage généré, /tmp/kernel.s
. avec un éditeur de texte tel que vim
. Accédez à unwind_backtrace+0x0/0xf8
, C'est-à-dire recherchez l'adresse de unwind_backtrace
+ Le offset
. Enfin, vous avez localisé la partie problématique dans votre code source.
Utilisez gdb
:
OMI, une option encore plus élégante consiste à utiliser la seule et unique gdb
. En supposant que vous disposez de la chaîne d'outils appropriée sur votre machine hôte:
gdb <path-to-vmlinux>
.list *(unwind_backtrace+0x10)
.Pour plus d'informations, vous pouvez vérifier les éléments suivants:
Dans
unwind_backtrace+0x0/0xf8
ce que le+0x0/0xf8
signifie?
Le premier nombre (+0x0
) est le décalage par rapport au début de la fonction (unwind_backtrace
dans ce cas). Le deuxième nombre (0xf8
) est le longueur totale de la fonction. Compte tenu de ces deux informations, si vous avez déjà une idée de l'endroit où le défaut s'est produit, cela pourrait suffire à confirmer votre suspicion (vous pouvez dire (approximativement) à quel point vous étiez dans la fonction).
Pour obtenir la ligne source exacte de l'instruction correspondante (généralement meilleure que les intuitions), utilisez addr2line
ou les autres méthodes dans d'autres réponses.