2012-04-16 3 views
18

Se sei fortunato quando il modulo del tuo kernel si blocca, otterrai un oops con un log con molte informazioni, come i valori nei registri, ecc. Una di queste informazioni è la traccia dello stack (lo stesso vale per i core dump, ma all'inizio avevo chiesto questo per i moduli del kernel). Prendete questo esempio:Come sfruttare al meglio lo stack trace (dal kernel o core dump)?

[<f97ade02>] ? skink_free_devices+0x32/0xb0 [skin_kernel] 
[<f97aba45>] ? cleanup_module+0x1e5/0x550 [skin_kernel] 
[<c017d0e7>] ? __stop_machine+0x57/0x70 
[<c016dec0>] ? __try_stop_module+0x0/0x30 
[<c016f069>] ? sys_delete_module+0x149/0x210 
[<c0102f24>] ? sysenter_do_call+0x12/0x16 

La mia ipotesi è che il +<number1>/<number2> ha qualcosa a che fare con l'offset dalla funzione in cui si è verificato l'errore. Cioè, controllando questo numero, forse guardando l'output del gruppo, dovrei essere in grado di scoprire la linea (meglio ancora, l'istruzione) in cui si è verificato questo errore. È corretto?

La mia domanda è: quali sono esattamente questi due numeri? Come li usi?

risposta

19
skink_free_devices+0x32/0xb0 

Ciò significa che l'istruzione è all'origine 0x32 byte dall'inizio della funzione skink_free_devices() che è lungo 0xB0 byte in totale.

Se si compila il kernel con -g abilitato, allora si può ottenere il numero di riga all'interno funzioni in cui il controllo è saltato utilizzando lo strumento addr2line o il nostro buon vecchio gdb

Qualcosa di simile

$ addr2line -e ./vmlinux 0xc01cf0d1 
/mnt/linux-2.5.26/include/asm/bitops.h:244 
or 
$ gdb ./vmlinux 
... 
(gdb) l *0xc01cf0d1 
0xc01cf0d1 is in read_chan (include/asm/bitops.h:244). 
(...) 
244  return ((1UL << (nr & 31)) & (((const volatile unsigned int *) addr)[nr >> 5])) != 0; 
(...) 

Così basta dare l'indirizzo che si desidera controllare a addr2line o gdb e devono dirvi il numero di riga nel file di origine in cui è presente la funzione incriminata Vedere l'articolo this per I dettagli completi

EDIT:vmlinux è la versione non compressa del kernel utilizzato per il debug e si trova di solito @/lib/modules/$(uname -r)/build/vmlinux, se avete costruito il vostro kernel da fonti. vmlinuz che trovate in /boot è il kernel compressa e non può essere che utile per il debug

+0

NON sapevo che puoi gdb il linux stesso! Questo e spettacolare! – Shahbaz

+0

Dove si trova 'vmlinux'? Ho pensato che sarebbe stato il kernel di Linux stesso (in/boot) ma che è 'vmlinuz ...' e addr2line dice "Formato file non riconosciuto" Non è un grosso problema, dato che sono più interessato ai miei moduli. – Shahbaz

+0

@Shahbaz vmlinuz è solo la versione compressa e/o spogliata di 'vmlinux'. BOth sarà generalmente nascosto nella cartella '/ boot'. Non ho il mio box Linux con me per controllare ora. Google in giro per i due :) Ecco alcuni antipasti. [One] (http://superuser.com/questions/62575/where-is-vmlinux-on-my-ubuntu-installation) e [Two] (http://superuser.com/questions/298826/how-do -i-uncompress-vmlinuz-to-vmlinux) –

1

Per gli utenti Emacs, here s' è una modalità importante di saltare facilmente intorno all'interno della traccia dello stack (utilizza addr2line internamente).

Disclaimer: L'ho scritto :)

+0

Ora per crearne uno solo per ViM ... – Shahbaz

+0

C'è qualcosa per vim (scusate per necro): https://github.com/rzwisler/oops_trace.vim/blob/master/plugin/oops_trace.vim – stellarhopper