2011-12-08 6 views
5

Sto provando a eseguire il debug di un software con gdbserver su ARM per ottenere un backtrace di un arresto anomalo. Purtroppo ricevo solo punti interrogativi. Ovunque, leggo questo problema è semplicemente correlato alla mancanza di simboli, ma i simboli non vengono rimossi dalle mie librerie.Solo punti interrogativi in ​​backtrace segnalati da gdb su ARM

Se cerco di usare il comando file per caricare i simboli nel client ottengo:

reading symbols from <path>/libQtWebKit.so.4.7.2...(no debugging symbols found)...done. 

e poi, quando si verifica l'incidente:

Program received signal SIGSEGV, Segmentation fault. 
0x00000000 in ??() 
(gdb) bt 
#0 0x00000000 in ??() 
#1 0x4bf38b88 in ??() 
Backtrace stopped: previous frame identical to this frame (corrupt stack?) 

mie librerie sono compilati nel rilascio ma i simboli sono effettivamente lì. Con nm posso trovarli. Perché ottengo solo punti interrogativi? Questo è solo perché le librerie sono compilate con l'ottimizzazione? Non è possibile eseguire il debug con le librerie in modalità di rilascio?

risposta

2

La nota corrupt stack è probabilmente il tuo problema. Sembra un indirizzo di ritorno o una voce della tabella virtuale o qualcosa è stato sovrascritto con zeri e quindi il controllo è stato trasferito lì. Anche se hai simboli disponibili, quegli indirizzi non puntano a simboli validi. Da qui il segfault.

Non invidio il tuo compito. Questi sono alcuni dei bug più difficili da rintracciare e possono persino spostarsi o temporaneamente andare via quando si apportano modifiche al codice per cercare di catturarli. La tua migliore scommessa è di solito qualcosa come git bisect o il tuo equivalente VCS per trovare il commit che l'ha introdotto. Spero che non sia troppo difficile da riprodurre.

+1

Sfortunatamente questa è una modifica di WebKit. Non esiste una versione precedente da ripristinare. Qualche altro modo di eseguire il debug? Forse valgrind? –

1

Un trucco che a volte è possibile utilizzare quando si ottiene il problema "SEGV a indirizzo 0" è quello di inserire manualmente l'indirizzo di ritorno dalla parte superiore dello stack nel pc e provare a eseguire una traccia di stack da lì. Ciò presuppone che devi indirizzare 0 effettuando una chiamata indiretta tramite un puntatore NULL, che è il modo più comune per ottenere l'indirizzo 0.

Ora non ho molta familiarità con ARM, ma su un PC x86, dovresti fare:

(gdb) set $eip = *(void **)$esp 
(gdb) set $esp = $esp + 4 

e poi fare un altro backtrace per capire dove sei veramente.

Se si riesce a capire la convenzione di chiamata utilizzata per ARM dal compilatore, si dovrebbe essere in grado di fare qualcosa di simile.