クラッシュダンプ、メモリダンプ、コアダンプ、システムダンプ…すべて同じ結果が得られます。つまり、特定の時間(通常はアプリケーションがクラッシュしたとき)のアプリケーションのメモリの状態を含むファイルです。
これらのファイルの処理方法を知っていると、障害の根本的な原因を見つけるのに役立ちます。開発者でなくても、システムで作成されたダンプファイルは、ソフトウェアを理解するのに非常に役立ちます(また、親しみやすいものになります)。
これは実践的な記事であり、次のコマンドを使用してサンプルアプリケーションリポジトリのクローンを作成することで、例を追うことができます。
git clone https://github.com/hANSIc99/core_dump_example.git
その他のLinuxリソース
- Linuxコマンドのチートシート
- 高度なLinuxコマンドのチートシート
- 無料のオンラインコース:RHELの技術概要
- Linuxネットワーキングのチートシート
- SELinuxチートシート
- Linuxの一般的なコマンドのチートシート
- Linuxコンテナとは何ですか?
- 最新のLinux記事
シグナルは、オペレーティングシステムとユーザーアプリケーション間の一種のプロセス間通信です。 Linuxは、POSIX標準で定義されているシグナルを使用します。システムでは、/usr/include/bits/signum-generic.h
で定義されている標準信号を見つけることができます。 。アプリケーションでシグナルを使用する方法について詳しく知りたい場合は、有益なmanシグナルページもあります。簡単に言えば、Linuxはシグナルを使用して、予期されたものか予期されなかったかに基づいて、さらなるアクティビティをトリガーします。
実行中のアプリケーションを終了すると、通常、アプリケーションはSIGTERM
を受け取ります。 信号。このタイプの終了信号が予期されるため、このアクションはメモリダンプを作成しません。
次のシグナルにより、ダンプファイルが作成されます(ソース:GNU Cライブラリ):
- SIGFPE:誤った算術演算
- SIGILL:違法な指示
- SIGSEGV:ストレージへの無効なアクセス
- SIGBUS:バスエラー
- SIGABRT:プログラムによって検出され、abortを呼び出すことによって報告されたエラー
- SIGIOT:Fedoraで古風なラベルが付けられており、このシグナルは
abort()
でトリガーするために使用されていました PDP-11で、SIGABRTにマップされるようになりました
core_dump_example
に移動します ディレクトリ、make
を実行します 、-c1
を使用してサンプルを実行します スイッチ:
./coredump -c1
アプリケーションは状態4で終了し、エラーが発生するはずです:
「Abgebrochen(Speicherabzug geschrieben)」は、大まかに「セグメンテーション違反(コアダンプ)」に変換されます。
コアダンプを作成するかどうかは、プロセスを実行しているユーザーのリソース制限によって決まります。 ulimit
を使用してリソース制限を変更できます コマンド。
コアダンプ作成の現在の設定を確認してください:
ulimit -c
unlimited
を出力する場合 、次に(推奨)デフォルトを使用しています。それ以外の場合は、次のコマンドで制限を修正してください:
ulimit -c unlimited
コアダンプのタイプの作成を無効にするには:
ulimit -c 0
数値は、リソースをキロバイト単位で指定します。
コアダンプとは何ですか?
カーネルがコアダンプを処理する方法は、次のように定義されています。
/proc/sys/kernel/core_pattern
Fedora 31を実行していますが、私のシステムでは、ファイルに次のものが含まれています。
/usr/lib/systemd/systemd-coredump %P %u %g %s %t %c %h
これは、コアダンプがsystemd-coredump
に転送されることを示しています 効用。 core_pattern
の内容 Linuxディストリビューションのさまざまなフレーバー間で大きく異なる可能性があります。 systemd-coredump
の場合 が使用中の場合、ダンプファイルは/var/lib/systemd/coredump
の下に圧縮されて保存されます 。ファイルに直接触れる必要はありません。代わりに、coredumpctl
を使用できます 。例:
coredumpctl list
システムに保存されている利用可能なすべてのダンプファイルが表示されます。
coredumpctl dump
を使用 、最後に保存されたダンプファイルから情報を取得できます:
[stephan @ localhost core_dump_example] $./coredump
アプリケーションが開始されました…
(……。)
メッセージ:ユーザーのプロセス4598(コアダンプ) 1000個のダンプされたコア。
スレッド4598のスタックトレース:
#0 0x00007f4bbaf22625 __GI_raise(libc.so.6)
#1 0x00007f4bbaf0b8d9 __GI_abort(libc.so.6)
#2 0x00007f4bbaf664af __libc_message(libc.so.6)
#3 0x00007f4bbaf6da9c malloc_printerr(libc.so.6)
#4 0x00007f4bbaf6f49c _int_free(libc.so.6)
#5該当なし(/ home / stephan / Dokumente / core_dump_example / coredump)
#6 0x00000000004013b1該当なし(/ home / stephan / Dokumente / core_dump_example / coredump)
#7 0x00007f4bbaf0d1a3 __libc_start_main(libc.so. 6)
#8 0x000000000040113e該当なし(/ home / stephan / Dokumente / core_dump_example / coredump)
コアをttyにダンプすることを拒否します(シェルリダイレクトを使用するか、—出力を指定します)。
これは、プロセスがSIGABRT
によって停止されたことを示しています 。このビューのスタックトレースには関数名が含まれていないため、あまり詳細ではありません。ただし、coredumpctl debug
を使用する場合 、デバッガー(デフォルトではGDB)でダンプファイルを開くだけです。 bt
と入力します (バックトレースの略)より詳細なビューを取得するには:
コアは`./coredump-c1'によって生成されました。
プログラムはシグナルSIGABRTで終了し、中止されました。
#0 __GI_raise(sig =sig @ entry =6)at ../sysdeps/unix /sysv/linux/raise.c:50
50 return ret;
(gdb)bt
#0 __GI_raise(sig =sig @ entry =6)at ../sysdeps/unix/ sysv / linux / raise.c:50
#1 0x00007fc37a9aa8d9 in __GI_abort()at abort.c:79
#2 0x00007fc37aa054af in __libc_message(action =action @ entry =do_abort、fmt =fmt @ entry =0x7fc37ab14f4b "%s \ n")at ../sysdeps/posix/libc_fatal.c:181
#3 0x00007fc37aa0ca9c in malloc_printerr(str =str @ entry =0x7fc37ab130e0 "free():invalid pointer")atmalloc。 c:5339
#4 0x00007fc37aa0e49c in _int_free(av =、p = 、have_lock =0)at malloc.c:4173
#5 0x000000000040120e in freeSomething(void *) ()
#6 0x0000000000401401 in main()
メモリアドレス:main()
およびfreeSomething()
後続のフレームと比較してかなり低いです。共有オブジェクトは仮想アドレス空間の最後の領域にマップされるため、SIGABRT
共有ライブラリでの呼び出しが原因でした。共有オブジェクトのメモリアドレスは呼び出し間で一定ではないため、呼び出し間でアドレスが異なる場合はまったく問題ありません。
スタックトレースは、後続の呼び出しがmalloc.c
から発信されていることを示しています 、これは、メモリ(割り当て解除)のあるものが間違っている可能性があることを示しています。
ソースコードでは、(C ++の知識がなくても)メモリ管理関数によって返されないポインタを解放しようとしたことがわかります。これにより、未定義の動作が発生し、SIGABRT
が発生します :
void freeSomething(void * ptr){
free(ptr);
}
int nTmp =5;
int * ptrNull =&nTmp;
freeSomething( ptrNull);
systemdコアダンプユーティリティは、/etc/systemd/coredump.conf
で構成できます。 。ダンプファイルのクリーニングのローテーションは、/etc/systemd/system/systemd-tmpfiles-clean.timer
で構成できます。 。
coredumpctl
に関する詳細情報を見つけることができます マニュアルページにあります。
Makefile
を開きます 9行目の最後の部分をコメントアウトします。これで次のようになります。
CFLAGS =-Wall -Werror -std=c++11 -g
-g
スイッチを使用すると、コンパイラはデバッグ情報を作成できます。今回は-c2
を使用してアプリケーションを起動します スイッチ:
./coredump -c2
浮動小数点例外が発生します。次のコマンドでGDBのダンプを開きます:
coredumpctl debug
今回は、エラーの原因となったソースコードの行を直接指し示しています。
/ home / stephan / Dokumente / core_dump_example/coredumpからシンボルを読み取る…
[新しいLWP6218]
コアは`./coredump-c2'によって生成されました。
プログラムはシグナルで終了しましたSIGFPE、算術例外。
#0 0x0000000000401233 in zeroDivide()at main.cpp:29
29 nRes =5 / nDivider;
(gdb)
list
と入力します ソースコードの概要を把握するには:
(gdb)list
24 int zeroDivide(){
25 int nDivider =5;
26 int nRes =0;
27 while(nDivider> 0){
28 nDivider-;
29 nRes =5 / nDivider;
30}
31 return nRes;
32}コマンド
info locals
を使用します アプリケーションが失敗した時点からローカル変数の値を取得するには:(gdb)info locals
nDivider =0
nRes =5ソースコードと組み合わせると、ゼロ除算に遭遇したことがわかります。
nRes = 5 / 0
結論 ダンプファイルの処理方法を知っていると、アプリケーションで再現が難しいランダムなバグを見つけて修正するのに役立ちます。また、アプリケーションでない場合は、コアダンプを開発者に転送すると、開発者が問題を見つけて修正するのに役立ちます。
Linux