2013-05-24 3 views
12

Ich habe einen Kernel oops in einem Linux-Gerätetreiber schrieb ich. Ich möchte feststellen, welche Zeile für die oops verantwortlich ist. Ich habe folgende Ausgabe, aber ich weiß nicht, wie ich sie interpretiere.Wie Adressen in einem Kernel zu interpretieren oops

Bedeutet das, dass mein Code bei der Anweisung write_func + 0x63 abgestürzt ist? Wie kann ich den Wert in EIP auf meine eigene Funktion beziehen? Was bedeuten die Werte nach dem Backslash?

[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 ]--- 
+0

Das ist genau das, was es bedeutet. In diesem Fall scheinen Sie abgestürzt zu sein, als Sie einen Interrupt auslieferten, der etwas mit Ihrem 'write_func()' zu tun haben könnte oder auch nicht. Ein vollständiger Trace- oder Quellcode wäre nützlicher. –

+0

Ich habe eine vollständige Stack-Trace hinzugefügt. Was bedeutet der Wert nach dem Backslash? Z.B. write_func + 0x63/_0x160_ –

+1

@HansThen write_func + 0x63/0x160 ist das Symbol + Offset/Länge. Schauen Sie sich diesen Artikel an: http://www.linuxforu.com/2011/01/understanding-a-kernel-oops/ –

Antwort

24

die Informationen, die Sie brauchen, ist genau dort:

[10991.880354] BUG: unable to handle kernel NULL pointer dereference at (null) 

, dass der Grund ist.

[10991.880359] IP: [<c06969d4>] iret_exc+0x7d0/0xa59 

Das ist der Befehlszeiger zum Zeitpunkt des Fehlers. Wir werden kurz darauf zurückkommen.

[10991.880365] *pdpt = 000000002258a001 *pde = 0000000000000000 

Dies sind physische Seitentabelleneinträge. die Deskriptor-Tabelle und den Seiten-Deskriptor-Eintrag. Letzteres ist natürlich NULL, da es ein NULL-Zeiger ist. Die oben genannten Werte sind selten nützlich (nur in Fällen, in denen eine physische Speicherzuordnung erforderlich ist)

[10991.880368] Oops: 0002 [#1] PREEMPT SMP 

Das ist der Oops-Code. PREEMPT SMP zeigt Ihnen, dass der Kernel präemptiv ist und für SMP kompiliert wurde, und nicht für UP. Dies ist wichtig für die Fälle, wo der Fehler von einer Race-Bedingung ist, usw.

[10991.880371] last sysfs file: /sys/devices/platform/coretemp.3/temp1_input 

Das ist nicht unbedingt die Täter, aber oft ist. Sys-Dateien werden von verschiedenen Kernel-Modulen exportiert, und oft führt eine E/A-Operation in der sys-Datei zur fehlerhaften Ausführung des Modul-Codes.

Der Kernel weiß nicht unbedingt, welches Modul zu beschuldigen ist, also gibt es Ihnen alle. Es kann auch sehr gut sein, dass ein kürzlich entladenes Modul nicht aufgeräumt hat und einige Rückstände (wie einen Timer oder Callback) im Kernel hinterlassen hat - was ein klassischer Fall für Ups oder Panik ist. Der Kernel meldet also auch den letzten unbelasteten.

[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. 

Wenn der fehlerhafte Thread ein Benutzermodus-Thread ist, erhalten Sie die PID und die Befehlszeile. „Tainted“ Flags sind die Art und Weise des Kernels zu sagen, es ist nicht ein Kernel-Fehler (die Kernel-Source ist offen und „rein“. „Taint“ stammt aus den blasphemischen Nicht-GPL-Module und andere.

[10991.880408] EIP: 0060:[<c06969d4>] EFLAGS: 00210246 CPU: 0 
[10991.880411] EIP is at iret_exc+0x7d0/0xa59 

Das gibt Sie die Verwerfungen Befehlszeiger, sowohl direkt als auch in Symbol + Offset-Form. der Teil nach dem Schrägstrich die Größe der Funktion ist.

[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 

die Register werden hier gezeigt. Ihre NULL ist wahrscheinlich EAX.

[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 

Der Bereich in der Nähe des Stapelzeigers wird angezeigt. Der Kernel hat keine Ahnung, was diese Werte bedeuten, aber sie sind die gleiche Ausgabe, die Sie von gdb erhalten würden, wenn Sie $ sp anzeigen. Es liegt also an dir, herauszufinden, was sie sind. (Zum Beispiel ist c03718c1 wahrscheinlich eine Kernel-Return-Adresse - Sie können also nach/proc/kallsyms gehen, um es herauszufinden, oder darauf vertrauen, dass es sich in der Ablaufverfolgung befindet, so wie es ist, als nächstes).Dies zeigt Ihnen, dass alle Daten, um es der Stapelrahmen ist

Nun, da Sie den Stapel Rufverfolgung haben, können Sie die Fragmente zusammen:

[10991.880423] 00000000 0000018c 00000000 0000018c e5e903dc e4616353 --> back to write_func 

[   ] ..................................................... 00000009 df99735c 
[10991.880428] df900a7c df900a7c b7837000 df80ad80 df99735c 00000009 e46182a4 e2a81f70 
[10991.880433] e28cd800 e09fc840 e28cd800 fffffffb e09fc888 c03718c1 --> back to proc_file_write 

[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 

Wieder Kernel kann nicht auseinander für Sie (es ist oopsing, und könnte sehr gut Panik, geben Sie ihm eine Pause!). Sie können diese Werte jedoch mithilfe von gdb zerlegen.

So jetzt wissen Sie alles. Sie können Ihr eigenes Modul tatsächlich zerlegen und herausfinden, wo genau in write_func der NULL-Zeiger dereferenziert wird. (Sie übergeben es wahrscheinlich als Argument für eine Funktion).

+0

+1: Ausgezeichnete und gründliche Grundierung! – wallyk

+0

Thx sehr viel. Genau die Information, nach der ich gesucht habe. –

+0

die beste Erklärung aller Zeiten ThankQ so sehr –