2013-05-24 13 views
12

Mam kernel ups w sterowniku urządzenia linux, który napisałem. Chcę określić, która linia jest odpowiedzialna za ups. Mam następujące wyniki, ale nie wiem, jak to interpretować.Jak interpretować adresy w jądrze oops

Czy to oznacza, że ​​mój kod rozbił się na instrukcji write_func + 0x63? Jak mogę powiązać wartość w EIP z moją własną funkcją? Co oznaczają wartości po odwrotnym ukośniku?

[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

To dokładnie to oznacza. W tym przypadku wydaje się, że uległa awarii podczas obsługi przerwania, co może, ale nie musi mieć coś wspólnego z 'write_func()'. Pełen ślad lub kod źródłowy byłby bardziej przydatny. –

+0

Dodałem pełny ślad stosu. Co oznacza wartość po ukośniku odwrotnym? Na przykład. write_func + 0x63/_0x160_ –

+1

@HansThen write_func + 0x63/0x160 to symbol + odsunięcie/długość. Sprawdź ten artykuł: http://www.linuxforu.com/2011/01/understanding-a-kernel-oops/ –

Odpowiedz

24

Wszystkie informacje potrzebne jest prawo tam:

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

To jest powód.

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

To jest wskaźnik instrukcji w momencie wystąpienia usterki. Wrócimy do tego na chwilę.

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

Są to fizyczne wpisy w tabeli stron. tablica deskryptorów i wpis deskryptora strony. Oczywiście ten drugi ma wartość NULL, ponieważ jest to wskaźnik NULL. Powyższe wartości są rzadko przydatne (tylko w przypadkach, gdy wymagane jest mapowanie pamięci fizycznej).

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

To jest kod oops. PREEMPT SMP pokazuje, że jądro jest wywłaszczane i skompilowane dla SMP, zamiast UP. Jest to ważne w przypadkach, gdy błąd jest od jakiegoś wyścigu, itp

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

To nie koniecznie winowajcą, ale często jest. Pliki sys są eksportowane przez różne moduły jądra, a często operacja I/O w pliku sys prowadzi do błędnego wykonania kodu modułu.

[10991.880374] Modules linked in: ... [last unloaded: preloadtrace] 

Jądro niekoniecznie wie, który moduł jest odpowiedzialny, więc daje je wszystkie. Również może być dobrze, że niedawno wyładowany moduł nie oczyścił się i pozostawił trochę pozostałości (np. Jakiś zegar lub oddzwonienie) w jądrze - co jest klasycznym przypadkiem dla oops lub paniki. Więc jądro również zgłasza ostatni niezaładowany.

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

Jeśli wątek zakłócający jest wątkiem trybu użytkownika, otrzymuje się PID i wiersz poleceń. „Tainted” flagi są sposobem przez jądro mówiąc to nie jest wina jądra (źródło jądra jest otwarty i „czysty”. „Skaza” pochodzi od bluźnierczych modułów non-GPL, i innych.

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

To daje Ci faulting wskaźnik instrukcji, zarówno bezpośrednio, jak i na symbol + przesunięcie formularza. część po ukośniku jest wielkość tej funkcji.

[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 

rejestrów są pokazane tutaj. Twój NULL jest prawdopodobne 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 

Wyświetlany jest obszar w pobliżu wskaźnika stosu. Jądro nie ma pojęcia, co oznaczają te wartości, ale są one takie same, jak w przypadku gdb wyświetlającego $ rsp. Więc od ciebie zależy, kim są. (Na przykład, c03718c1 jest prawdopodobnie adresem zwrotnym jądra - możesz więc przejść do/proc/kallsyms, aby to zrozumieć, lub polegać na tym, że jest w śladzie, tak jak jest, dalej).Ten mówi, że wszystkie dane do niego jest ramka stosu

teraz, bo masz ślad stosu wywołań, można umieścić fragmenty razem:

[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 

Ponownie, kernel nie można demontować dla Ty (to jest oopsing i może bardzo panikować, daj sobie spokój!). Ale możesz użyć gdb do deasemblowania tych wartości.

Teraz już wszystko wiesz. Można faktycznie zdemontować własny moduł i dowiedzieć się, gdzie dokładnie w write_func NULL wskaźnik jest dereferenced. (Prawdopodobnie przekazujesz to jako argument do jakiejś funkcji).

+0

+1: Doskonały i dokładny podkład! – wallyk

+0

Thx bardzo. Tylko informacje, których szukałem. –

+0

najlepsze wytłumaczenie, jakie kiedykolwiek dziękowałem –