Comment interpréter les adresses d'un kernel oops
J'ai un kernel oops dans un linux pilote de périphérique j'ai écrit. Je veux déterminer qui est chargé de la oups. J'ai le résultat suivant, mais je ne sais pas comment l'interpréter.
T-il dire que mon code s'est écrasé à l'instruction à write_func + 0x63? Comment puis-je relier la valeur de EIP pour mon propre fonction? Que signifient les valeurs après la barre oblique inverse veux dire?
[10991.880354] BUG: unable to handle kernel NULL pointer dereference at (null)
[10991.880359] IP: [<c06969d4>] iret_exc+0x7d0/0xa59
[10991.880365] *pdpt = 000000002258a001 *pde = 0000000000000000
[10991.880368] Oops: 0002 [#1] PREEMPT SMP
[10991.880371] last sysfs file: /sys/devices/platform/coretemp.3/temp1_input
[10991.880374] Modules linked in: nfs lockd fscache nfs_acl auth_rpcgss sunrpc hdrdmod(F) coretemp(F) af_packet fuse edd cpufreq_conservative cpufreq_userspace cpufreq_powersave acpi_cpufreq mperf microcode dm_mod ppdev sg og3 ghes i2c_i801 igb hed pcspkr iTCO_wdt dca iTCO_vendor_support parport_pc floppy parport ext4 jbd2 crc16 i915 drm_kms_helper drm i2c_algo_bit video button fan processor thermal thermal_sys [last unloaded: preloadtrace]
[10991.880400]
[10991.880402] Pid: 4487, comm: python Tainted: GF 2.6.37.1-1.2-desktop #1 To be filled by O.E.M. To be filled by O.E.M./To be filled by O.E.M.
[10991.880408] EIP: 0060:[<c06969d4>] EFLAGS: 00210246 CPU: 0
[10991.880411] EIP is at iret_exc+0x7d0/0xa59
[10991.880413] EAX: 00000000 EBX: 00000000 ECX: 0000018c EDX: b7837000
[10991.880415] ESI: b7837000 EDI: 00000000 EBP: b7837000 ESP: e2a81ee0
[10991.880417] DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068
[10991.880420] Process python (pid: 4487, ti=e2a80000 task=df940530 task.ti=e2a80000)
[10991.880422] Stack:
[10991.880423] 00000000 0000018c 00000000 0000018c e5e903dc e4616353 00000009 df99735c
[10991.880428] df900a7c df900a7c b7837000 df80ad80 df99735c 00000009 e46182a4 e2a81f70
[10991.880433] e28cd800 e09fc840 e28cd800 fffffffb e09fc888 c03718c1 e4618290 0000018c
[10991.880438] Call Trace:
[10991.882006] Inexact backtrace:
[10991.882006]
[10991.882012] [<e4616353>] ? write_func+0x63/0x160 [mymod]
[10991.882017] [<c03718c1>] ? proc_file_write+0x71/0xa0
[10991.882020] [<c0371850>] ? proc_file_write+0x0/0xa0
[10991.882023] [<c036c971>] ? proc_reg_write+0x61/0x90
[10991.882026] [<c036c910>] ? proc_reg_write+0x0/0x90
[10991.882031] [<c0323060>] ? vfs_write+0xa0/0x160
[10991.882034] [<c03243c6>] ? fget_light+0x96/0xb0
[10991.882037] [<c0323331>] ? sys_write+0x41/0x70
[10991.882040] [<c0202f0c>] ? sysenter_do_call+0x12/0x22
[10991.882044] [<c069007b>] ? _lock_kernel+0xab/0x180
[10991.882046] Code: f3 aa 58 59 e9 5a f9 d7 ff 8d 0c 88 e9 12 fa d7 ff 01 d9 e9 7b fa d7 ff 8d 0c 8b e9 73 fa d7 ff 01 d9 eb 03 8d 0c 8b 51 50 31 c0 <f3> aa 58 59 e9 cf fa d7 ff 01 d9 e9 38 fb d7 ff 8d 0c 8b e9 30
[10991.882069] EIP: [<c06969d4>] iret_exc+0x7d0/0xa59 SS:ESP 0068:e2a81ee0
[10991.882072] CR2: 0000000000000000
[10991.889660] ---[ end trace 26fe339b54b2ea3e ]---
C'est exactement ce que cela signifie. Dans ce cas, vous semblez avoir écrasé tout en servant une interruption, ce qui peut ou peut ne pas avoir quelque chose à faire avec votre
J'ai ajouté une pleine trace de la pile. Quelle est la valeur après la barre oblique inverse veux dire? E. g. write_func+0x63/_0x160_
write_func+0x63/0x160 est le symbole + offset/longueur. Découvrez cet article: linuxforu.com/2011/01/understanding-a-kernel-oops
write_func()
. Une trace complète ou de code source serait plus utile.J'ai ajouté une pleine trace de la pile. Quelle est la valeur après la barre oblique inverse veux dire? E. g. write_func+0x63/_0x160_
write_func+0x63/0x160 est le symbole + offset/longueur. Découvrez cet article: linuxforu.com/2011/01/understanding-a-kernel-oops
OriginalL'auteur Hans Then | 2013-05-24
Vous devez vous connecter pour publier un commentaire.
Toutes les informations dont vous avez besoin est là:
C'est la raison.
C'est le pointeur d'instruction au moment de la faute. Nous allons revenir à ce que momentanément.
Ce sont physiques entrées de table de page. le descripteur de la table, et la page d'entrée du descripteur. Naturellement, celle-ci est NULLE, puisque c'est un pointeur NULL. Les valeurs ci-dessus ne sont que rarement utiles (uniquement dans le cas où la mémoire physique de la cartographie est nécessaire)
C'est le oops de code. SMP PREEMPT vous montre le noyau est preemptible, et compilé pour SMP, plutôt que de l'. C'est important pour les cas où le bug est à partir de certaines condition de course, etc.
Ce n'est pas forcément le coupable, mais il est. sys fichiers sont exportés par les différents modules du noyau, et souvent une opération d'e/S sur les fichiers sys conduit à l'défectueux module d'exécution de code.
Le noyau ne le sait pas nécessairement le module qui est à blâmer, c'est de vous donner tous les. Aussi, il se peut très bien que récemment déchargé module n'a pas de nettoyer et de gauche des résidus (à l'instar de certains de la minuterie, ou de rappel) dans le noyau, qui est un cas classique pour oops ou de la panique. De sorte que le noyau des rapports de la dernière déchargé, en tant que bien.
Si le thread défaillant est un mode utilisateur thread, vous obtenez le PID et de la ligne de commande. "Entaché" les drapeaux sont le noyau de la façon de le dire n'est pas un noyau de faute (le noyau de la source est ouvert et "pur". "Souillure" vient de l'blasphématoire non-GPL modules, et d'autres.
Qui vous donne les failles pointeur d'instruction, à la fois directement et en symbole+décalage de forme. La partie après le slash est la taille de la fonction.
Les registres sont présentés ici. Votre valeur NULL est probable EAX.
La zone à proximité du pointeur de pile est affiché. Le noyau n'a aucune idée de ce que ces valeurs moyennes, mais ils sont de la même sortie que vous obtiendrez à partir de gdb affichage de l' $rsp. Donc, c'est à vous de comprendre ce qu'ils sont. (Par exemple, c03718c1 est un noyau adresse de retour probable de sorte que vous pouvez aller à /proc/kallsyms pour le comprendre, ou s'appuyer sur d'être dans la trace, tel qu'il est , prochaine). Cela vous indique que toutes les données jusqu'à il est la trame de pile
Maintenant, parce que vous avez la pile d'appel de trace, vous pouvez mettre l'ensemble les fragments:
Encore une fois, le noyau ne peux pas le démonter pour vous (c'est oopsing, et pourrait très bien la panique, lui donner une pause!). Mais vous pouvez utiliser gdb pour démonter ces valeurs.
Alors maintenant que vous savez tout. Vous pouvez en fait démonter votre propre module et de déterminer où exactement dans write_func le pointeur NULL est déréférencé. (Vous avez probablement passer en argument à une fonction).
Merci beaucoup. Juste l'info que je cherchais.
la meilleure explication que jamais ThankQ tellement
OriginalL'auteur Technologeeks