GNU/Linux >> Linux の 問題 >  >> Linux

Linuxダンプファイルの作成とデバッグ

クラッシュダンプ、メモリダンプ、コアダンプ、システムダンプ…すべて同じ結果が得られます。つまり、特定の時間(通常はアプリケーションがクラッシュしたとき)のアプリケーションのメモリの状態を含むファイルです。

これらのファイルの処理方法を知っていると、障害の根本的な原因を見つけるのに役立ちます。開発者でなくても、システムで作成されたダンプファイルは、ソフトウェアを理解するのに非常に役立ちます(また、親しみやすいものになります)。

これは実践的な記事であり、次のコマンドを使用してサンプルアプリケーションリポジトリのクローンを作成することで、例を追うことができます。

 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
  1. プロのようにLinuxでファイルとディレクトリを探す

  2. Linuxでファイルをアーカイブおよび圧縮する方法

  3. Linuxネットワークのトラブルシューティングとデバッグ?

  1. Linuxで最大のファイルとディレクトリを探す

  2. Linux ファイルとディレクトリの削除

  3. Linux でのファイルとディレクトリの作成と削除

  1. Linuxでのディレクトリの作成、削除、および管理

  2. Linuxで.gzファイルと.tar.gzファイルを抽出する方法

  3. Linux – Unix / linux Osesの標準および/または共通ディレクトリ?