ubuntuでのコアダンプのデバッグ

Linux環境でプログラムを実行すると、次のように、セグメント障害(「セグメント障害」)が表示され、同時にコアダンプが表示される場合があります。

[1]15428 segmentation fault(core dumped)./a.out

以下は、私がオンラインで見つけたsegfaultの定義と説明です。

A segmentation fault(often shortened to segfault) is a particular error condition that can occur during the operation of computer software. In short, a segmentation fault occurs when a program attempts to access a memory location that it is not allowed to access, or attempts to access a memory location in a way that is not allowed(e.g., attempts to write to a read-only location, or to overwrite part of the operating system). Systems based on processors like the Motorola 68000 tend to refer to these events as Address or Bus errors.

Segmentation is one approach to memory management and protection in the operating system. It has been superseded by paging for most purposes, but much of the terminology of segmentation is still used,"segmentation fault" being an example. Some operating systems still have segmentation at some logical level although paging is used as the main memory management policy.

On Unix-like operating systems, a process that accesses invalid memory receives the SIGSEGV signal. On Microsoft Windows, a process that accesses invalid memory receives the STATUS_ACCESS_VIOLATION exception.

簡単に理解すると、アクセスしてはならないメモリにアクセスすると、segfaultが発生します。
コアダンプは、エラー時のコールスタックなどの情報をファイルに書き込んで、後続のデバッグを容易にする方法です。 Ubuntuでは、コアダンプを正しくデバッグするためにいくつかの設定が必要です。以下に詳細な説明を示します。

ulimit設定###

ulimitは、シェル起動プロセスが占めるシステムリソースを制限するためのツールです。詳細な手順については、[こちら](https://www.ibm.com/developerworks/cn/linux/l-cn-ulimit/)を参照してください。 Ubuntuではデフォルトのコアファイルサイズが0であるため、ここでulimitを設定する必要があります。 ulimit -aを実行して、すべてのオプション設定を表示できます。

$ ulimit -a
- t: cpu time(seconds)              unlimited
- f: file size(blocks)              unlimited
- d: data seg size(kbytes)          unlimited
- s: stack size(kbytes)8192-c: core file size(blocks)0-m: resident setsize(kbytes)      unlimited
- u: processes                       2063144-n: file descriptors                1024-l: locked-in-memory size(kbytes)64-v: address space(kbytes)          unlimited
- x: file locks                      unlimited
- i: pending signals                 2063144-q: bytes in POSIX msg queues       819200-e: max nice                        0-r: max rt priority                 0-N 15:                              unlimited

上記の結果の -c:コアファイルサイズ(ブロック)の値は0であることがわかります。したがって、セグメンテーションフォールトでコアダンプが発生した場合、デフォルトではコアファイルは生成されません。
コアファイルのサイズを変更するにはどうすればよいですか? ulimitの値は ulimit -kvの形式で設定できます。ここで、 -kは上記の結果の最初の列、 vは設定値であり、最大値は unlimitedに設定できます。次のように設定できます。

ulimit -c unlimited

もう一度 ulimit -aを使用して、 -cの変更が有効になっていることを確認してください。

$ ulimit -a
- t: cpu time(seconds)              unlimited
- f: file size(blocks)              unlimited
- d: data seg size(kbytes)          unlimited
- s: stack size(kbytes)8192-c: core file size(blocks)         unlimited
- m: resident setsize(kbytes)      unlimited
- u: processes                       2063144-n: file descriptors                1024-l: locked-in-memory size(kbytes)64-v: address space(kbytes)          unlimited
- x: file locks                      unlimited
- i: pending signals                 2063144-q: bytes in POSIX msg queues       819200-e: max nice                        0-r: max rt priority                 0-N 15:                              unlimited
注:新しいシェルを開くと、ulimitオプションがデフォルトのオプションに復元され、値をリセットする必要があります

core_pattern ###を設定します

上記のulimit設定の後、 core_pattern、つまりコアダンプの送信後にコアファイルで実行される操作も設定する必要があります。これは、Ubuntu16.04にある / proc / sys / kernel / core_patternファイルを表示することで取得できます。 、上記のファイルの内容は次のとおりです。

$ cat /proc/sys/kernel/core_pattern
| /usr/share/apport/apport %p %s %c %P

lは次のコマンドを実行することを意味し、後者の apportはUbuntuのバグフィードバック用のツールです。したがって、Ubuntuでは、デフォルトのコアダンプsegfault処理メカニズムは、バグ検査のバグとして処理します。バグの場合は報告してください。
この設定では、gdbを使用してプログラムのエラーをデバッグすることはできません。
したがって、ここでは、 core_patternの内容を変更し、それを coreに変更する必要があります。ただし、 core_patternファイルは物理ファイル自体ではないため、変更する方法はありません。この機能を実現するためのちょっとしたコツがあります。apportサービスを一時停止します。

sudo service apport stop

次に、 core_patternの内容を確認します。

$ cat /proc/sys/kernel/core_pattern
core

ここで操作を確認し、それを coreに変更してコアファイルを生成できます。

gcc / g ++はデバッグモードを設定します###

上記の2つの設定に加えて、コードのコンパイル時に -gパラメーターを追加してデバッグモードを有効にする必要があります。これにより、生成された実行可能ファイルにデバッグ情報が追加されます。

g++-g xxx.cpp
gcc -g xxx.c

gdbを使用してプログラムをデバッグします###

上記の設定が完了したら、gdbを使用してデバッグできます。プログラムでセグメンテーションエラーが発生し、コアファイルも生成された場合は、次のコマンドを実行してデバッグを開始します。

gdb ./a.out core

その中で、 。/ a.outは実行可能ファイルへのパスであり、 coreはコアダンプによって生成されたファイルです。
次に、gdbデバッグ環境で btコマンドを実行してエラーの場所を特定し、検索エンジンを使用してエラーメッセージに基づいて解決策を見つけます。以下は私のデバッグサイト情報の1つです。

$ gdb ./build/tools/caffe.bin core
GNU gdb(Ubuntu 7.11.1-0ubuntu1~16.5)7.11.1Copyright(C)2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty"for details.
This GDB was configured as"x86_64-linux-gnu".
Type "show configuration"for configuration details.
For bug reporting instructions, please see:<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from./build/tools/caffe.bin...(no debugging symbols found)...done.[New LWP38035][Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Core was generated by `./build/tools/caffe.bin'.
Program terminated with signal SIGSEGV, Segmentation fault.
#00 x00007f99b6ff5f66in google::protobuf::Arena::AllocateAligned(std::type_info const*, unsigned long)()from/usr/local/lib/libopencv_dnn.so.3.3(gdb) bt
#00 x00007f99b6ff5f66in google::protobuf::Arena::AllocateAligned(std::type_info const*, unsigned long)()from/usr/local/lib/libopencv_dnn.so.3.3
#10 x00007f99b6ff5f89in google::protobuf::Arena::AddListNode(void*,void(*)(void*))()from/usr/local/lib/libopencv_dnn.so.3.3
#20 x00007f99b70473aein google::protobuf::FileDescriptorProto::New(google::protobuf::Arena*)const[clone .localalias.409]()from/usr/local/lib/libopencv_dnn.so.3.3
#30 x00007f99b6147038in google::protobuf::MessageLite::ParseFromArray(voidconst*, int)()from/usr/lib/x86_64-linux-gnu/libprotobuf.so.9
#40 x00007f99b61901b6in google::protobuf::EncodedDescriptorDatabase::Add(voidconst*, int)()from/usr/lib/x86_64-linux-gnu/libprotobuf.so.9
#50 x00007f99b61519b8in google::protobuf::DescriptorPool::InternalAddGeneratedFile(voidconst*, int)()from/usr/lib/x86_64-linux-gnu/libprotobuf.so.9
#60 x00007f99b618048cin google::protobuf::protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto()()from/usr/lib/x86_64-linux-gnu/libprotobuf.so.9
#70 x00007f99b7e346baincall_init(l=<optimized out>, argc=argc@entry=1, argv=argv@entry=0x7ffe8743a4d8, env=env@entry=0x7ffe8743a4e8) at dl-init.c:72
#80 x00007f99b7e347cbincall_init(env=0x7ffe8743a4e8, argv=0x7ffe8743a4d8, argc=1, l=<optimized out>) at dl-init.c:30
#9_ dl_init(main_map=0x7f99b804b168, argc=1, argv=0x7ffe8743a4d8, env=0x7ffe8743a4e8) at dl-init.c:120
#100 x00007f99b7e24c6ain_dl_start_user()from/lib64/ld-linux-x86-64.so.2
#110 x0000000000000001in??()
#120 x00007ffe8743c1cbin??()
#130 x0000000000000000in??()(gdb)

参照###

  1. https://www.ibm.com/developerworks/cn/linux/l-gccrtl/index.html
  2. https://www.ibm.com/developerworks/cn/linux/l-cn-ulimit/

Recommended Posts

ubuntuでのコアダンプのデバッグ
Ubuntuにmysql-pythoをインストールします
ubuntuサーブのNagios3
ubuntuでスーパーバイザーを使用する
Ubuntuにpythonをインストールする
Ubuntu19.10にJDKをインストールします
UbuntuでのAnacondaの使用
UbuntuにHelmをインストールする方法
ubuntuでのJenkinsのハッピーインストール
ubuntuでhanlpを使用する方法
ubuntuマルチユーザーでディスククォータを使用する
Ubuntu14.04にmysqlをインストールする方法
UbuntuにDockerをインストールして構成する
Ubuntuでのgitlabのインストール手順
Ubuntu14.04にmysqlをインストールする方法
Linuxの基本(Ubuntuのroot権限)
Ubuntu16.04でLaravel5.4を5.6にアップグレードする手順