2013-11-24 17 views
15

Zastanawiam się, czy możliwe jest uruchomienie aplikacji za pośrednictwem GDB, na SegFault zapisanie śledzenia wstecznego do pliku (aby obejrzeć później), a następnie zamknij GDB wszystkie bez wprowadzania danych przez użytkownika.backtrace gdb bez wprowadzania danych przez użytkownika?

Używam aplikacji ze skryptu powłoki w nieskończonej pętli (więc jeśli ulegnie awarii ponownie) na rozruch systemu operacyjnego z nieinteraktywnej sesji. Aplikacja ulega awarii w sposób niemożliwy do odtworzenia, więc potrzebuję śledzenia wstecznego z awarii, aby rozwiązać problem. Najlepiej byłoby zmodyfikować skrypt powłoki, aby uwzględnić funkcję debugowania + śledzenia wstecznego GDB i zachować automatyczne ponowne uruchamianie aplikacji po awarii.

Czy można to zrobić?

+2

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

+2

Nie można włączyć rdzenia pliki w systemie i uzyskać w ten sposób ślad wstecz? Wydaje się to dużo łatwiejsze niż pętla gdb. –

+0

'więc potrzebuję backtrace z awarii do debugowania problemu." - Nie znalazłem odpowiedzi, dlaczego nie można przeanalizować pliku core z awarii? Czy to dlatego, że jest dość duży? –

Odpowiedz

17

Podziękowania dla Aditya Kumar; akceptowalne rozwiązanie:

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

1

ten współpracuje z gdb 7.6:

Mój program testowy, który powoduje zrzutu pamięci, jeśli jest podany parametr wiersza poleceń:

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; 
} 

Mój skrypt 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") 

Najpierw uruchamiam a.out nie ma awarii. Żadne pliki dziennika utworzone są:

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

Następny biegnę a.out i nadać mu jeden parametr :

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

I to jest raport awarii:

>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

Ewentualnie po prostu przechowywania ślad, można umieścić ulimit -c unlimited przed swoją nieskończoną pętlą w skrypcie powłoki. Rezultat będzie taki, że za każdym razem, gdy twój program ulegnie awarii, zapisze zrzut rdzenia w pliku, który w moim systemie nazywa się właśnie core, ale w innych systemach może zawierać identyfikator procesu. Jeśli program segfault (widzisz to ze stanu wyjścia równego 139), po prostu przenieś plik core w bezpieczne miejsce, używając unikalnej nazwy (na przykład używając znaczników czasu). Dzięki tym podstawowym plikom i gdb możesz zrobić jeszcze więcej, niż tylko spojrzeć na backtrace. Tak więc myślę, że używanie ich może być nawet bardziej użyteczne dla ciebie.