魔法の呪文
LD_PRELOAD=/lib/libSegFault.so someapp
多くの異なる場所someapp
で説明されているように、SIGSEGV に関するバックトレース情報を提供する libSegFault.so で実行されます。
signal(7)
のようなアプローチを使用しSIGABRT
てハンドラーを呼び出す以外SIGSEGV
に、libSegFault にassert(3)
障害のバックトレース情報を提供させる方法はありますか?
env SEGFAULT_SIGNALS="abrt segv" LD_PRELOAD=/lib/libSegFault.so someapp
プリロード ライブラリへの実際のパスは異なる場合があることに注意してください。私のマシンでは、私は使用します
env SEGFAULT_SIGNALS="abrt segv" LD_PRELOAD=/lib/x86_64-linux-gnu/libSegFault.so some-64bit-app
また
env SEGFAULT_SIGNALS="abrt segv" LD_PRELOAD=/lib/i386-linux-gnu/libSegFault.so some-32bit-app
私が実行していたアプリケーションが 64 ビットまたは 32 ビットのどちらでコンパイルされたかによって異なります。file
(チェックに使えます。)
ソースは、のlibSegFault.so
動作を定義する 3 つの環境変数があることを示しています。
SEGFAULT_SIGNALS
: スタック トレースを引き起こすシグナルのリスト。デフォルトは ですSIGSEGV
。定義されているが空SEGFAULT_SIGNALS
の場合は、スタック トレースを引き起こすシグナルがないことを意味します。サポートされている値はsegv
、SIGBUS シグナルを持つシステム、SIGSTKFLT シグナルをill
持つシステムabrt
、およびこれらすべてのシステムでは、、、、です。fpe
bus
stkflt
all
SEGFAULT_USE_ALTSTACK
: 環境で定義されている場合libSegFault.so
、スタック トレース シグナルに代替スタックを使用します。これは、スタックの破損をデバッグしている場合に便利です。
SEGFAULT_OUTPUT_NAME
: 環境で定義されている場合、スタック トレースは標準エラーの代わりにこのファイルに書き込まれます。
正直なところ、私はこれらを最初にライブラリを調べて見つけましたstrings /lib/libSegFault.so | sed -e '/[^0-9A-Z_]/ d'
。すべての標準ライブラリ ( libSegFault.so
GNU C ライブラリの一部になっている) は環境変数を介して調整できるため、そのコマンドのようなものを使用して、環境変数名のように見える文字列をダンプすると、検索するものをすばやく見つけることができます。で Web 検索を行うと"SEGFAULT_SIGNALS" "SEGFAULT_OUTPUT_NAME"
、多数の有用なリンクが生成されます。それが最近の GNU C ライブラリの一部であることがわかったので、ソースのgit アーカイブにアクセスし、ライブラリの実際のソース ファイルを見つけて、回答を投稿しました。
同様に、glibc 例外ハンドラーは、/dev/console
ヒープ破損エラーでスタック ダンプを書き込みます。
非 tty (つまり、systemd プロセスまたはその他の切り離されたプロセス) で実行可能ファイルを実行している場合、クラッシュ出力は に送られますが/dev/null
、これはあまり役に立ちません。
出力を にリダイレクトする、文書化されていない機能があります/dev/stderr
。次の環境変数を設定します。
export LIBC_FATAL_STDERR_=1
これは、最大のフォレンジックのために libSegFault.so と組み合わせて使用できます。
また、SIGABRT のバックトレースも有効にすると、これにより 2 つのスタック トレースが得られる可能性があることにも言及する価値があります。glibc は最初にスタック トレースを実行し、次に SIGABRT を通知し、次に libSegFault が 2 番目のスタック トレースを提供するためです。