2013-11-24 8 views
15

Mi chiedo se sia possibile avviare un'applicazione tramite GDB, su un SegFault scrivere il backtrace su un file (per guardare più avanti), quindi uscire da GDB senza alcun input dell'utente.backtrace gdb senza input dell'utente?

Sto eseguendo un'applicazione da uno script di shell in un ciclo infinito (quindi se si blocca si ricarica) all'avvio del sistema operativo da una sessione non interattiva. L'applicazione si blocca in modo non riproducibile, quindi ho bisogno di un backtrace dall'arresto anomalo per eseguire il debug del problema. Idealmente, dovrei solo modificare lo script della shell per includere la funzionalità di debugging + backtracing di GDB e preservare il riavvio automatico dell'applicazione dopo un crash.

È possibile fare questo?

+2

http://www.commandlinefu.com/commands/view/4039/print-stack-trace-of-a-core-file-without-needing-to-enter-gdb-interactively –

+2

Impossibile abilitare il core file sul tuo sistema e ottenere il backtrace in questo modo? Sembra molto più semplice di un ciclo gdb. –

+0

'quindi ho bisogno di un backtrace dall'arresto anomalo per eseguire il debug del problema. - Non ho trovato una risposta perché non è possibile analizzare un file core da un arresto anomalo? È perché è abbastanza grande? –

risposta

17

Grazie a Aditya Kumar; soluzione accettabile:

gdb -batch -ex "run" -ex "bt" ${my_program} 2>&1 | grep -v ^"No stack."$

1

Questo funziona con gdb 7.6:

Il mio programma di test che causa un core dump se viene dato un parametro di riga di comando:

int a(int argc) 
{ 
    if (argc > 1) { 
    int *p = 0; 
    *p = *p +1; 
    return *p; 
    } 
    else { 
    return 0; 
    } 
} 

int b(int argc) 
{ 
    return a(argc); 
} 

int main(int argc, char *argv[]) 
{ 
    int res = b(argc); 
    return res; 
} 

Il mio script python my_check .py:

def my_signal_handler (event): 
    if (isinstance(event, gdb.SignalEvent)): 
    log_file_name = "a.out.crash." + str(gdb.selected_inferior().pid) + ".log" 
    gdb.execute("set logging file " + log_file_name) 
    gdb.execute("set logging on") 
    gdb.execute("set logging redirect on") 
    gdb.execute("thread apply all bt") 
    gdb.execute("q") 

gdb.events.stop.connect(my_signal_handler) 
gdb.execute("set confirm off") 
gdb.execute("set pagination off") 
gdb.execute("r") 
gdb.execute("q") 

Quindi, prima eseguo a.out e non c'è incidente. non vengono creati i file di log:

gdb q -x my_check.py --args ./a.out>/dev/null

Successivo corro a.out e dare un parametro :

>gdb -q -x my_check.py --args ./a.out 1 >/dev/null 

E questo è un crash report:

>cat a.out.crash.13554.log 

Thread 1 (process 13554): 
#0 0x0000000000400555 in a (argc=2) at main.cpp:5 
#1 0x000000000040058a in b (argc=2) at main.cpp:15 
#2 0x00000000004005a3 in main (argc=2, argv=0x7fffffffe198) at main.cpp:20 
0

alternativa al solo memorizzare il backtrace, si potrebbe mettere ulimit -c unlimited davanti al tuo ciclo infinito nello script della tua shell. Il risultato sarà che ogni volta che il programma segnaults, scriverà un core dump in un file che sul mio sistema è chiamato semplicemente core ma su altri sistemi potrebbe includere l'id del processo. Se il programma segfaults (si vede che dal suo stato di uscita è uguale a 139), spostare semplicemente il file core in un percorso sicuro utilizzando un nome univoco (ad esempio utilizzando timestamp). Con questi file core e gdb puoi fare ancora di più che guardare il backtrace. Quindi penso che usarli potrebbe essere anche più utile per te.