2013-11-24 23 views
15

GDB üzerinden bir uygulama başlatmanın mümkün olup olmadığını merak ediyorum, bir SegFault üzerinde bir backtrace dosyasına (daha sonra bakmak için) yazın ve sonra kullanıcı girişi olmadan GDB'den çıkın.gdb backtrace?

Karmaşık olmayan bir oturumdan OS önyüklemesinde sonsuz bir döngüdeki bir kabuk komut dosyasından bir uygulama çalıştırıyorum (böylece çöker). Uygulama yeniden üretilemez bir şekilde çöküyor, bu yüzden sorunu gidermek için çökmeden bir backtrace gerekiyor. İdeal olarak, GDB hata ayıklama + backtracing işlevselliğini içerecek ve bir çökme sonrasında uygulamanın otomatik olarak yeniden başlatılmasını sağlayacak şekilde kabuk betiğini değiştirirdim.

Bunu yapmak mümkün mü?

+2

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

+2

Çekirdeği etkinleştiremez misiniz? sisteminizde dosyalar ve backtrace bu şekilde olsun? Bir gdb döngüsünden çok daha kolay görünüyor. –

+0

'Bu yüzden çökmeden hata ayıklamak için bir backtrace ihtiyacım var.' - Bir çekirdek dosya neden bir çarpışmadan analiz edemiyorum bir cevap bulamadık? Bu oldukça büyük olduğu için mi? –

cevap

17

Aditya Kumar'a teşekkürler; olarak kabul edilebilir bir çözelti:

Bu GDB 7.6 ile çalışır gdb -batch -ex "run" -ex "bt" ${my_program} 2>&1 | grep -v ^"No stack."$

1

:

bir parametre hattı verilmesi halinde bir çekirdek dökümü neden Benim test programı:

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

My piton komut 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") 

İlk önce, kaza yok. Hiçbir günlük dosyaları oluşturulur:

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

Sonraki Ben a.out koşmak ve ona bir parametre vermek :

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

Ve bu kilitlenme raporu:

Alternatif
>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

sadece geri izleme saklamak için, size 012 koyabilirsinizkabuk komut dosyanızdaki sonsuz döngünüzün önünde. Sonuç, programınız her defasında kesildiğinde, sistemimde core adı verilen bir dosyaya çekirdek dökümü yazacaktır, ancak diğer sistemlerde işlem kimliğini içerebilir. Program segfaults (bunu çıkış durumundan 139'a eşittir) görürseniz, core dosyasını benzersiz bir ad kullanarak güvenli bir konuma taşıyın (örneğin zaman damgalarını kullanarak). Bu çekirdek dosyalar ve gdb ile daha sonra backtrace'e bakmaktan daha fazlasını yapabilirsiniz. Bu yüzden bunları kullanmanın sizin için daha yararlı olabileceğini düşünüyorum.