Finora, con gdb + qemu, posso passare al/sul codice sorgente del kernel di Linux. È possibile eseguire il debug dei programmi di spazio utente contemporaneamente? Ad esempio, passo singolo un programma dallo spazio utente allo spazio del kernel in modo da poter osservare le modifiche dei registri sul monitor qemu emettendo info registers
?È possibile utilizzare gdb e qemu per eseguire il debug di programmi di spazio utente Linux e di spazio kernel contemporaneamente?
risposta
L'ho raggiunto utilizzando il comando gdb add-symbol-file per aggiungere informazioni sul debug dei programmi in userspace. Ma devi sapere che questi programmi stanno caricando gli indirizzi. per essere precisi, devi avviare il debug del kernel collegando gdb a gdbserver come al solito; e quindi, è possibile aggiungere le informazioni di debug del programma. Puoi anche usare lo script .gdbinit. Leggi this
minima configurazione passo-Setep
, ma qui è un fully automated QEMU + Buildroot example che presuposes che already know how to debug the kernel with QEMU + gdb e exaplanation più dettagliato:
readelf -h myexecutable | grep Entry
ottiene:
Entry point address: 0x4003a0
Quindi all'interno di GDB dobbiamo fare:
add-symbol-file myexecutable 0x4003a0
b main
E solo allora avviare l'eseguibile in QEMU:
myexecutable
Un modo più affidabile per farlo è quello di impostare myexecutable
come il processo init
se si può fare questo.
Perché mai dovresti farlo al posto di gdbserver
?
posso vedere solo caso dell'utilizzazione per questa finora: debug init
: Debug init on Qemu using gdb
Altrimenti, perché non utilizzare il seguente metodo più affidabile, ad esempio al passaggio in una chiamata di sistema:
- inizio due GDB remoti:
- uno con
qemu-system-* -s
- altra
gdbserver myexecutable
come spiegato in: https://reverseengineering.stackexchange.com/questions/8829/cross-debugging-for-mips-elf-with-qemu-toolchain/16214#16214
- uno con
- passo GDB
gdbserver
s' più vicino il più possibile alla chiamata di sistema, che spesso significa entrare nella libc - sul GDB di QEMU, ad esempio
b sys_read
per la chiamata di sistema di lettura - indietro
gdbserver
, farecontinue
Propongo questo perché:
- utilizzando il QEMU GDB per userland può portare a salti casuali come il contesto kernel passa a un altro processo che utilizza gli stessi indirizzi virtuali
Non è stato possibile caricare correttamente le librerie condivise senza
gdbserver
: il tentativo disharedlibrary
invia direttamente:(gdb) sharedlibrary ../../staging/lib/libc.so.0 No loaded shared libraries match the pattern `../../staging/lib/libc.so.0'.
Di conseguenza, poiché la maggior parte delle interazioni del kernel passare attraverso lo stdib, si avrebbe bisogno di fare un sacco di montaggio intelligente fare un passo per trovare la voce del kernel, che potrebbe essere impraticabile.
Fino a quando qualcuno scrive uno script GDB più intelligente che esegue tutte le istruzioni finché non si verifica un interruttore di contesto o finché l'origine non diventa disponibile. Mi chiedo se tali script non sarebbero troppo lenti, poiché l'approccio ingenuo ha il sovraccarico della comunicazione con GDB per ogni istruzione.
Questo potrebbe iniziare: Tell gdb to skip standard files
Perché no? Per vedere un cambio di attività, prova a passare da ['__schedule'] (http://lxr.free-electrons.com/source/kernel/sched/core.c?v=3.17#L2753), specificatamente nel modo giusto" "al nuovo compito. Altrimenti, prova a impostare i breakpoint su varie chiamate di sistema per vedere cosa succede quando un processo li chiama. –
Grazie Jonathon, ma posso interrompere quando il programma è ancora in esecuzione in userspace? In realtà sono più interessato a osservare i registri quando il processo è in esecuzione nello spazio utente. –
@JeffLi sei riuscito a eseguire il debug di un programma spaziale utente in qemu? Sto cercando di fare lo stesso, ma non riesco a capire come –