「coreファイルの取得」の編集履歴(バックアップ)一覧はこちら

coreファイルの取得 - (2010/05/01 (土) 23:44:25) の1つ前との変更点

追加された行は緑色になります。

削除された行は赤色になります。

coreファイルは、プログラムの異常(セグメンテーションフォルトなど)や、killコマンドなどにより、プログラムが特定のシグナルを受信した際に取得されます。 coreファイルに関しては[[man core>http://www.linux.or.jp/JM/html/LDP_man-pages/man5/core.5.html]]にいろいろ書いてあるので、そちらを見た方がよいのですが、ここでは単純にcoreとるために必要なことだけ書いて置きます。 **coreが取得されるシグナル #region  以下はPOSIX.1-1990に定められたシグナルで、動作にCoreとあるシグナルを受信するとcoreが取得されます。 |CENTER:BGCOLOR(#EEE8AA):No|CENTER:BGCOLOR(#EEE8AA):シグナル名|CENTER:BGCOLOR(#EEE8AA):シグナル番号|CENTER:BGCOLOR(#EEE8AA):動作|CENTER:BGCOLOR(#EEE8AA):コメント| |CENTER:1 |CENTER:SIGINT |CENTER:2 |CENTER:Term |CENTER:キーボードからの割り込み (Interrupt) | |CENTER:2 |CENTER:SIGQUIT |CENTER:3 |CENTER:Core |CENTER:キーボードによる中止 (Quit) | |CENTER:3 |CENTER:SIGILL |CENTER:4 |CENTER:Core |CENTER:不正な命令 | |CENTER:4 |CENTER:SIGABRT |CENTER:6 |CENTER:Core |CENTER:abort(3) からの中断 (Abort) シグナル | |CENTER:5 |CENTER:SIGFPE |CENTER:8 |CENTER:Core |CENTER:浮動小数点例外 | |CENTER:6 |CENTER:SIGKILL |CENTER:9 |CENTER:Term |CENTER:Kill シグナル | |CENTER:7 |CENTER:SIGSEGV |CENTER:11 |CENTER:Core |CENTER:不正なメモリ参照 | |CENTER:8 |CENTER:SIGPIPE |CENTER:13 |CENTER:Term |CENTER:パイプ破壊: 読み手の無いパイプへの書き出し | |CENTER:9 |CENTER:SIGALRM |CENTER:14 |CENTER:Term |CENTER:alarm(2) からのタイマーシグナル | |CENTER:10|CENTER:SIGTERM |CENTER:15 |CENTER:Term |CENTER:終了 (termination) シグナル | |CENTER:11|CENTER:SIGUSR1 |CENTER:10 |CENTER:Term |CENTER:ユーザ定義シグナル 1 | |CENTER:12|CENTER:SIGUSR2 |CENTER:12 |CENTER:Term |CENTER:ユーザ定義シグナル 2 | |CENTER:13|CENTER:SIGCHLD |CENTER:17 |CENTER:Ign |CENTER:子プロセスの一時停止 (stop) または終了 | |CENTER:14|CENTER:SIGCONT |CENTER:18 |CENTER:Cont |CENTER:一時停止 (stop) からの再開 | |CENTER:15|CENTER:SIGSTOP |CENTER:19 |CENTER:Stop |CENTER:プロセスの一時停止 (stop) | |CENTER:16|CENTER:SIGTSTP |CENTER:20 |CENTER:Stop |CENTER:端末 (tty) より入力された一時停止 (stop) | |CENTER:17|CENTER:SIGTTIN |CENTER:21 |CENTER:Stop |CENTER:バックグランドプロセスの tty 入力 | |CENTER:18|CENTER:SIGTTOU |CENTER:22 |CENTER:Stop |CENTER:バックグランドプロセスの tty 出力 | #endregion **取得場所とファイル名 #region  coreが取得される場所は、受信したプログラムが動作しているカレントディレクトリです。  ファイル名は、通常は '&bold(){core}' もしくは '&bold(){core.<PID>}' という名称で取得されます。ファイル名は「&bold(){/proc/sys/kernel/core_pattern}」により変更可能です(詳細は[[man core>http://www.linux.or.jp/JM/html/LDP_man-pages/man5/core.5.html]]参照)。 #endregion **core取得の制限サイズ #region  coreファイルには取得サイズの制限値があり、ulimitコマンドで見ることができます。 >$ ulimit -a <ーーcoreサイズ以外も表示。coreのみ見たいときは ulimit -c >core file size (blocks, -c) 0  <ーー1Kbyte単位。この例だと0Kbyte > ・・・以下省略  上記の例だと0Kbyteのためcoreは取得されません。サイズ変更は、一時的に変更するなら以下のコマンドを実行します(実行したシェルとその子プロセスでのみ有効)。 >$ ulimit -c <サイズ>  or $ ulimit -c unlimited ・・・後者は無限大とする  永続的に変更するには以下のファイルを修正します。 >/etc/security/limits.conf #endregion **coreの取得方法 #region  killコマンドを使う場合は、以下のようにします。 >$ kill -<動作がcoreのシグナル番号> <対象プロセスのPID>  ただし、このkillを使うと対象プロセスも終了してしまいます。終了させたくない場合は、gdbのgcoreコマンドを使います。 >$ gdb >(gdb) attach <対象プロセスのPID> >(gdb) gcore <ファイル名> >(gdb) detach  これだと、人がコマンドをインタラクティブに入力しないといけないため、自動的にcoreを取得させるなどには使えません。  そのためRHELやCentOSでは、gdbのgcoreコマンドをshスクリプトで実装した&bold(){gcore}コマンドがあります。 >$ gcore >usage: gcore [-o filename] pid  ディストリビューションによってgcoreコマンドがない場合があるので、[[gcoreコマンド]]にCentOS5.4のgcoreコマンドの内容を書いておきます。gdbがないことはないと思うので、どのディストリビューションでも使えると思います。 #endregion ** Google coredumper #region  Google codeに[[coredumper>http://code.google.com/p/google-coredumper/]]というプロジェクトがあります。  gcoreのように、プロセスを止めずにcoreを取得するためのライブラリです。  shとは関係ありませんが、core取得ということでここに使いかたを書いておきます。 ■インストール  [[http://code.google.com/p/google-coredumper/]]からダウンロードし、適当なところに展開します。試したときは &bold(){coredumper-1.2.1.tar.gz} が最新でした。  展開した中のINSTALLファイルにインストール方法がかかれていますが、Linuxの標準的なconfigure、make、make installのパターンでインストール可能です。  なお、以下のようにするとdebパッケージやrpmパッケージも作れるということで、make installはせずに、make rpm をして、rpmを作成してインストールしました。 >`make deb` - builds Debian packages >`make rpm` - build RedHat RPM packages  rpmの作成先はmake rpmした際に表示されます。 >$ make rpm >  ・・・ >The rpm package file(s) are located in /home/test/Soft/develop/coredumper-1.2.1/packages/rpm-unknown >$ ls /home/tomonari/Soft/develop/coredumper-1.2.1/packages/rpm-unknown >coredumper-1.2.1-1.x86_64.rpm coredumper-devel-1.2.1-1.x86_64.rpm >coredumper-debuginfo-1.2.1-1.x86_64.rpm    coredumperはライブラリであり、プログラムから呼び出すためにはヘッダファイルも必要なため、以下の2つをインストールしました。 >$ sudo rpm -ivh coredumper-1.2.1-1.x86_64.rpm >$ ls /usr/lib/libcoredumper* >/usr/lib/libcoredumper.a /usr/lib/libcoredumper.so.1 >/usr/lib/libcoredumper.la /usr/lib/libcoredumper.so.1.0.0 >/usr/lib/libcoredumper.so >$ sudo rpm -ivh coredumper-devel-1.2.1-1.x86_64.rpm >$ ls /usr/include/google >coredumper.h ■使いかた  Webページに以下のように出ています。&bold(){coredumper.h}をincludeして、coreを取得したいところで&bold(){WriteCoreDump(coreファイル名)}とするだけですね。 >#include <google/coredumper.h> > ... > WriteCoreDump('core.myprogram'); > /* Keep going, we generated a core file, >  * but we didn't crash. >  */ ■サンプル ソース >#include <stdio.h> >#include <stdlib.h> >#include <string.h> >#include <errno.h> >#include <google/coredumper.h> > >int main(){ >  char *str; >  short svar; >  int ret,err; >  >  str = "Hello World"; >  svar = 0x1234; > >  ret = WriteCoreDump("core.test"); >  err = errno; >  if ( ret == -1 ){ >  strerror( err ); >  exit(1); >  } > >  printf("WriteCoreDump Success!! ret: %d\n",ret); >  exit(0); >} コンパイル・リンク >$ gcc -o main main.c -lcoredumper -g <-- libcoredumperのリンクが必要、-gはgdbで変数の値をみるため 実行 >$ ./main >WriteCoreDump Success!! ret: 0 >$ ls core.test >core.test >$ gdb -c core.test main <--本当にcore見られるか実験 > ・・・ >(gdb) bt >#0 0x00002b9b483a5825 in WriteCoreDump () from /usr/lib/libcoredumper.so.1 >#1 0x0000000000400628 in main () at main.c:16 >(gdb) up >#1 0x0000000000400628 in main () at main.c:16 >16 ret = WriteCoreDump("core.test"); >(gdb) p str >$1 = 0x400768 "Hello World" >(gdb) p /x svar >$2 = 0x1234 なお、coredumperの[[ここ>http://code.google.com/p/google-coredumper/wiki/GetCoreDump]]とか[[ここ>http://code.google.com/p/google-coredumper/wiki/WriteCoreDump]]を見ると、APIの説明があります。core取得時に圧縮もできたりするようです。 #endregion ----
coreファイルは、プログラムの異常(セグメンテーションフォルトなど)や、killコマンドなどにより、プログラムが特定のシグナルを受信した際に取得されます。 coreファイルに関しては[[man core>http://www.linux.or.jp/JM/html/LDP_man-pages/man5/core.5.html]]にいろいろ書いてあるので、そちらを見た方がよいのですが、ここでは単純にcoreとるために必要なことだけ書いて置きます。 &color(red){※長くなったので、コンテンツをたたんで見出しを見えるようにしています。+をクリックして見てください。} **coreが取得されるシグナル #region  以下はPOSIX.1-1990に定められたシグナルで、動作にCoreとあるシグナルを受信するとcoreが取得されます。 |CENTER:BGCOLOR(#EEE8AA):No|CENTER:BGCOLOR(#EEE8AA):シグナル名|CENTER:BGCOLOR(#EEE8AA):シグナル番号|CENTER:BGCOLOR(#EEE8AA):動作|CENTER:BGCOLOR(#EEE8AA):コメント| |CENTER:1 |CENTER:SIGINT |CENTER:2 |CENTER:Term |CENTER:キーボードからの割り込み (Interrupt) | |CENTER:2 |CENTER:SIGQUIT |CENTER:3 |CENTER:Core |CENTER:キーボードによる中止 (Quit) | |CENTER:3 |CENTER:SIGILL |CENTER:4 |CENTER:Core |CENTER:不正な命令 | |CENTER:4 |CENTER:SIGABRT |CENTER:6 |CENTER:Core |CENTER:abort(3) からの中断 (Abort) シグナル | |CENTER:5 |CENTER:SIGFPE |CENTER:8 |CENTER:Core |CENTER:浮動小数点例外 | |CENTER:6 |CENTER:SIGKILL |CENTER:9 |CENTER:Term |CENTER:Kill シグナル | |CENTER:7 |CENTER:SIGSEGV |CENTER:11 |CENTER:Core |CENTER:不正なメモリ参照 | |CENTER:8 |CENTER:SIGPIPE |CENTER:13 |CENTER:Term |CENTER:パイプ破壊: 読み手の無いパイプへの書き出し | |CENTER:9 |CENTER:SIGALRM |CENTER:14 |CENTER:Term |CENTER:alarm(2) からのタイマーシグナル | |CENTER:10|CENTER:SIGTERM |CENTER:15 |CENTER:Term |CENTER:終了 (termination) シグナル | |CENTER:11|CENTER:SIGUSR1 |CENTER:10 |CENTER:Term |CENTER:ユーザ定義シグナル 1 | |CENTER:12|CENTER:SIGUSR2 |CENTER:12 |CENTER:Term |CENTER:ユーザ定義シグナル 2 | |CENTER:13|CENTER:SIGCHLD |CENTER:17 |CENTER:Ign |CENTER:子プロセスの一時停止 (stop) または終了 | |CENTER:14|CENTER:SIGCONT |CENTER:18 |CENTER:Cont |CENTER:一時停止 (stop) からの再開 | |CENTER:15|CENTER:SIGSTOP |CENTER:19 |CENTER:Stop |CENTER:プロセスの一時停止 (stop) | |CENTER:16|CENTER:SIGTSTP |CENTER:20 |CENTER:Stop |CENTER:端末 (tty) より入力された一時停止 (stop) | |CENTER:17|CENTER:SIGTTIN |CENTER:21 |CENTER:Stop |CENTER:バックグランドプロセスの tty 入力 | |CENTER:18|CENTER:SIGTTOU |CENTER:22 |CENTER:Stop |CENTER:バックグランドプロセスの tty 出力 | #endregion **取得場所とファイル名 #region  coreが取得される場所は、受信したプログラムが動作しているカレントディレクトリです。  ファイル名は、通常は '&bold(){core}' もしくは '&bold(){core.<PID>}' という名称で取得されます。ファイル名は「&bold(){/proc/sys/kernel/core_pattern}」により変更可能です(詳細は[[man core>http://www.linux.or.jp/JM/html/LDP_man-pages/man5/core.5.html]]参照)。 #endregion **core取得の制限サイズ #region  coreファイルには取得サイズの制限値があり、ulimitコマンドで見ることができます。 >$ ulimit -a <ーーcoreサイズ以外も表示。coreのみ見たいときは ulimit -c >core file size (blocks, -c) 0  <ーー1Kbyte単位。この例だと0Kbyte > ・・・以下省略  上記の例だと0Kbyteのためcoreは取得されません。サイズ変更は、一時的に変更するなら以下のコマンドを実行します(実行したシェルとその子プロセスでのみ有効)。 >$ ulimit -c <サイズ>  or $ ulimit -c unlimited ・・・後者は無限大とする  永続的に変更するには以下のファイルを修正します。 >/etc/security/limits.conf #endregion **coreの取得方法 #region  killコマンドを使う場合は、以下のようにします。 >$ kill -<動作がcoreのシグナル番号> <対象プロセスのPID>  ただし、このkillを使うと対象プロセスも終了してしまいます。終了させたくない場合は、gdbのgcoreコマンドを使います。 >$ gdb >(gdb) attach <対象プロセスのPID> >(gdb) gcore <ファイル名> >(gdb) detach  これだと、人がコマンドをインタラクティブに入力しないといけないため、自動的にcoreを取得させるなどには使えません。  そのためRHELやCentOSでは、gdbのgcoreコマンドをshスクリプトで実装した&bold(){gcore}コマンドがあります。 >$ gcore >usage: gcore [-o filename] pid  ディストリビューションによってgcoreコマンドがない場合があるので、[[gcoreコマンド]]にCentOS5.4のgcoreコマンドの内容を書いておきます。gdbがないことはないと思うので、どのディストリビューションでも使えると思います。 #endregion ** Google coredumper #region  Google codeに[[coredumper>http://code.google.com/p/google-coredumper/]]というプロジェクトがあります。  gcoreのように、プロセスを止めずにcoreを取得するためのライブラリです。  shとは関係ありませんが、core取得ということでここに使いかたを書いておきます。 ■インストール  [[http://code.google.com/p/google-coredumper/]]からダウンロードし、適当なところに展開します。試したときは &bold(){coredumper-1.2.1.tar.gz} が最新でした。  展開した中のINSTALLファイルにインストール方法がかかれていますが、Linuxの標準的なconfigure、make、make installのパターンでインストール可能です。  なお、以下のようにするとdebパッケージやrpmパッケージも作れるということで、make installはせずに、make rpm をして、rpmを作成してインストールしました。 >`make deb` - builds Debian packages >`make rpm` - build RedHat RPM packages  rpmの作成先はmake rpmした際に表示されます。 >$ make rpm >  ・・・ >The rpm package file(s) are located in /home/test/Soft/develop/coredumper-1.2.1/packages/rpm-unknown >$ ls /home/tomonari/Soft/develop/coredumper-1.2.1/packages/rpm-unknown >coredumper-1.2.1-1.x86_64.rpm coredumper-devel-1.2.1-1.x86_64.rpm >coredumper-debuginfo-1.2.1-1.x86_64.rpm    coredumperはライブラリであり、プログラムから呼び出すためにはヘッダファイルも必要なため、以下の2つをインストールしました。 >$ sudo rpm -ivh coredumper-1.2.1-1.x86_64.rpm >$ ls /usr/lib/libcoredumper* >/usr/lib/libcoredumper.a /usr/lib/libcoredumper.so.1 >/usr/lib/libcoredumper.la /usr/lib/libcoredumper.so.1.0.0 >/usr/lib/libcoredumper.so >$ sudo rpm -ivh coredumper-devel-1.2.1-1.x86_64.rpm >$ ls /usr/include/google >coredumper.h ■使いかた  Webページに以下のように出ています。&bold(){coredumper.h}をincludeして、coreを取得したいところで&bold(){WriteCoreDump(coreファイル名)}とするだけですね。 >#include <google/coredumper.h> > ... > WriteCoreDump('core.myprogram'); > /* Keep going, we generated a core file, >  * but we didn't crash. >  */ ■サンプル ソース >#include <stdio.h> >#include <stdlib.h> >#include <string.h> >#include <errno.h> >#include <google/coredumper.h> > >int main(){ >  char *str; >  short svar; >  int ret,err; >  >  str = "Hello World"; >  svar = 0x1234; > >  ret = WriteCoreDump("core.test"); >  err = errno; >  if ( ret == -1 ){ >  strerror( err ); >  exit(1); >  } > >  printf("WriteCoreDump Success!! ret: %d\n",ret); >  exit(0); >} コンパイル・リンク >$ gcc -o main main.c -lcoredumper -g <-- libcoredumperのリンクが必要、-gはgdbで変数の値をみるため 実行 >$ ./main >WriteCoreDump Success!! ret: 0 >$ ls core.test >core.test >$ gdb -c core.test main <--本当にcore見られるか実験 > ・・・ >(gdb) bt >#0 0x00002b9b483a5825 in WriteCoreDump () from /usr/lib/libcoredumper.so.1 >#1 0x0000000000400628 in main () at main.c:16 >(gdb) up >#1 0x0000000000400628 in main () at main.c:16 >16 ret = WriteCoreDump("core.test"); >(gdb) p str >$1 = 0x400768 "Hello World" >(gdb) p /x svar >$2 = 0x1234 なお、coredumperの[[ここ>http://code.google.com/p/google-coredumper/wiki/GetCoreDump]]とか[[ここ>http://code.google.com/p/google-coredumper/wiki/WriteCoreDump]]を見ると、APIの説明があります。core取得時に圧縮もできたりするようです。 #endregion ----

表示オプション

横に並べて表示:
変化行の前後のみ表示: