2013-11-24 13 views
15

GDB経由でアプリケーションを起動し、SegFaultでバックトレースをファイルに書き込んだり(後で見る)、ユーザ入力なしでGDBをすべて終了することができるのだろうかと思います。ユーザ入力がないgdbバックトレース?

私は、非対話型セッションからOSブート時に無限ループのアプリケーションを実行しています(クラッシュした場合はリロードします)。アプリケーションは再現不可能な方法でクラッシュするので、問題をデバッグするためにクラッシュからのバックトレースが必要です。理想的には、シェルスクリプトを修正して、GDBのデバッグ+バックトレース機能を組み込み、クラッシュ後のアプリケーションの自動再起動を保持するだけです。

これは可能ですか?

+2

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

+2

コアを有効にすることはできますかあなたのシステム上のファイルを取得し、そのバックトレースを取得しますか?これはgdbループよりはるかに簡単です。 –

+0

'だから、問題をデバッグするためにクラッシュからのバックトレースが必要です。 ' - クラッシュの中核ファイルを解析できない理由を知りませんでしたか?それはかなり大きいからですか? –

答えて

17

Aditya Kumarに感謝します。受け入れ可能な解決策:

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

1

これは、GDB 7.6で動作します:

それは、コマンドラインパラメータを指定された場合にコア・ダンプが発生する私のテストプログラム:

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

私の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") 

したがって、最初にa.outを実行し、クラッシュはありません。ログ・ファイルは作成されません:

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

次は私がa.outを実行して、それを一つのパラメータを与えます:

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

そして、これは、クラッシュレポートです:

また
>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

だけのバックトレースを格納するために、あなたは012を置くことができますシェルスクリプトの無限ループの前にがあります。その結果、あなたのプログラムがsegfaultsするたびに、私のシステム上ではcoreと呼ばれるファイルにコアダンプが書き込まれますが、他のシステムにはプロセスIDが含まれることになります。プログラムがsegfaults(終了ステータスが139であることが分かる場合)、coreファイルを一意の名前(タイムスタンプなど)を使用して安全な場所に移動するだけです。これらのコアファイルとgdbを使用すると、バックトレースだけでなく、さらに多くのことを行うことができます。したがって、私はそれらを使用することがあなたにとってより有用かもしれないと思います。

関連する問題