回答:
より良い方法があるかもしれませんが、この種の方法はそれを自動化します。
以下を入れます~/backtrace
:
backtrace
quit
これをseg_wrapper.sh
パスのディレクトリで呼び出されるスクリプトに入れます。
#!/bin/bash
ulimit -c unlimited
"$@"
if [[ $? -eq 139 ]]; then
gdb -q $1 core -x ~/backtrace
fi
このulimit
コマンドにより、コアがダンプされます。"$@"
スクリプトに与えられた引数であるため、プログラムとその引数になります。$?
終了ステータスを保持します。139は、セグメンテーション違反に対する私のマシンのデフォルトの終了ステータスのようです。
以下のためにgdb
、-q
静かな(無イントロメッセージ)を意味し、-x
伝えるgdb
それに与えられたファイル内のコマンドを実行します。
それを使用するには、次のようにします。
seg_wrapper.sh ./mycommand and its arguments
2年後にここに来て申し訳ありません...他のものを探している間につまずいた。完全を期すためにこれを追加します。
1)受け入れられた答えは素晴らしいと思いますが、gdbが必要です。私がよく知っている方法ではlibSegFault.soを使用します。
でアプリを実行する場合
LD_PRELOAD = ... path-to ... / libSegFault.so myapp
バックトレース、ロードされたライブラリなどを含むレポートを取得します
2)アドレスをファイル名+行番号に変換catchsegv
するaddr2line
ために使用するラッパースクリプトも利用できます。
これらはコアファイルやgdbよりもはるかに軽いソリューションです(たとえば、組み込みシステムに適しています)
LD_PRELOAD=libSegFault.so
dlパスにある場合は問題ありません。
Ubuntuは(プロジェクトとして)Apportを使用してこれを行います。あなたは彼らがそれをどのようにしたかを見ることができます。
/proc/sys/kernel/core_pattern
次に、Kyle Brandtのスクリプトを少し修正したバリアントを示します。次の点で改善されています。
#!/bin/bash
gdbcommandfile=$(tempfile)
usepid=$(cat /proc/sys/kernel/core_uses_pid)
printf "set pagination off\nbacktrace\nquit\n" > $gdbcommandfile
ulimit -c unlimited
"$@"&
pid=$!
wait $!
if [[ $? -eq 139 ]]; then
if [[ $usepid == 1 ]]; then
gdb -q $1 core.$pid -x $gdbcommandfile
else
gdb -q $1 core -x $gdbcommandfile
fi
fi
rm $gdbcommandfile
-ex
代わりに使用します。 gdb ... -ex 'set pagination off' -ex backtrace -ex quit