web-dev-qa-db-fra.com

Comment lire, comprendre, analyser et déboguer une panique du noyau Linux?

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)
  • Dans unwind_backtrace+0x0/0xf8 ce que le +0x0/0xf8 signifie?
  • Comment puis-je voir le code C de unwind_backtrace+0x0/0xf8?
  • Comment interpréter le contenu de la panique?
40
0x90

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)

43
iabdalkader

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:

  1. 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
    
  2. 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:

  1. Exécutez gdb <path-to-vmlinux>.
  2. Exécutez dans l'invite de gdb: list *(unwind_backtrace+0x10).

Pour plus d'informations, vous pouvez vérifier les éléments suivants:

  1. Astuces de débogage du noya .
  2. Débogage du noyau Linux à l'aide de Gdb
21
0x90

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.

13
mgalgs