Comment lire, de comprendre, d'analyser et de déboguer un Linux kernel panic?
De considérer les éléments suivants noyau linux de vidage de pile, vous pouvez déclencher un mouvement de 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 la panique du contenu?
- Connexes: comment faire pour obtenir la trace complète: unix.stackexchange.com/questions/208260/... , les points d'interrogation: stackoverflow.com/questions/13113384/...
Vous devez vous connecter pour publier un commentaire.
C'est juste un ordinaire backtrace, ces fonctions sont appelées dans l'ordre inverse (d'abord appelé a été appelé par le précédent et ainsi de suite):
La
bdi_register+0xec/0x150
est le symbole + le décalage de longueur/il n'y a plus d'informations à ce sujet dans La compréhension d'un Kernel Oops et comment vous pouvez déboguer un kernel oops. Il y a également cet excellent tutoriel sur Débogage du NoyauRemarque: comme indiqué ci-dessous par Eugene, vous pouvez essayer de addr2line tout d'abord, il a encore besoin d'une image avec les symboles de débogage si, par exemple
addr2line -e vmlinux_with_debug_info 0019594c(+offset)
addr2line
pouvez résoudre l'adresse et déterminer les lignes de source. Bien sûr, il n'est pas toujours possible de cartographier les instructions à l'emplacement dans le code source, mais toujours mieux que rien. Les symboles de débogage pour le noyau pour cela, il faut, bien sûr. Si l'on est chanceux, ils peuvent être trouvés dans desvmlinux
lui-même (pour custom-built grains) ou dans un emballage séparé. Certaines distributions fournissent de tels ensembles, les noms peuvent varier.addr2line -e vmlinux_with_debug_info 0019594c
peut vous aider à trouver les lignes du code source correspondant àbdi_register+0xec
.addr2line
eteu-addr2line
(un outil similaire de elfutils package) et a constaté que ce dernier est plus fiable. J'ai utilisé à la fois pour résoudre une adresse en "e1000" pilote approprié avec les informations de débogage. J'ai copié le fichier avec les informations de débogage (e1000.ko.debug dans mon cas) sur une autre machine et tenté d'analyser avecaddr2line -f -e e1000.ko.debug -j .devinit.text 0x424
et la même chose aveceu-addr2line
. Seule cette dernière a donné des résultats corrects.addr2line
a fait à un mauvais endroit dans le code source,eu-addr2line
fait les choses. Je ne peux pas dire aujourd'hui pourquoi il est de cette façon, peut-être, quelque chose d'autre est nécessaire pouraddr2line
. En attendant, je vous recommande d'installer elfutils et à l'aide deeu-addr2line
.(receive_room.isra.9+0x8/0x4c)
.addr2line
fonctionne bien avec l'adresse complète (par exemple,addr2line -e vmlinux 4004578c
) et non avec le "symbole+offset" eteu-addr2line
l'inverse (par exemple,eu-addr2line -e vmlinux gwrr_balance.isra.20+0x11ac
donne le même queaddr2line
avec adresse complète)Voici 2 solutions de rechange pour
addr2line
. En supposant que vous avez la bonne cible de la chaîne, vous pouvez effectuer l'une des opérations suivantes:Utilisation
objdump
:localiser votre
vmlinux
ou la.ko
fichier sous le noyau répertoire racine, puis démonter le fichier de l'objet :Ouvrir l'assembly généré fichier,
/tmp/kernel.s
. avec un éditeur de texte tel quevim
. Aller àunwind_backtrace+0x0/0xf8
, c'est à dire la recherche de l'adresse deunwind_backtrace
+ leoffset
. Enfin, vous avez situé la problématique qui est dans votre code source.Utilisation
gdb
:De l'OMI, encore plus élégant option consiste à utiliser le seul et unique
gdb
. En supposant que vous avez le bon ensemble d'outils sur votre machine hôte:gdb <path-to-vmlinux>
.list *(unwind_backtrace+0x10)
.Pour plus d'informations vous pouvez commander la suivante:
gdb
ne fonctionne pas pour moi, même si tous les symboles de débogage sont inclus et j'ai pu effectuer le débogage à distance, dans le passé (je dois avoir changé quelque chose...).objdump
bien, produit une très belle liste, y compris le code source, ce qui était très précis et m'a montré le point de causer la panique.Le premier nombre (
+0x0
) est le décalage à partir du 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 éléments d'information, si vous avez déjà une idée sur l'endroit où la faute s'est produite, cela pourrait être suffisant pour confirmer vos soupçons (vous pouvez le dire (en gros) dans quelle mesure le long dans la fonction que vous étiez).Pour obtenir la source exacte de la ligne correspondant à l'enseignement (généralement mieux que les intuitions), l'utilisation
addr2line
ou d'autres méthodes dans d'autres réponses.