初めてのcore dump
初めてcore dumpをつかったデバッグをしたので、
記念に書きます!
core dumpを使う経緯としては、
apache+phpの環境でmessagesに「segmentation fault」というエラーが発生したからです。
segmentation fault?私は見たことがありません。。。
その発生個所を突き止めるために、「core dump」でデバッグするということになりました。
操作はroot権限でやります。
まず、必要なものをインストールします。
・gdb ・gcc ・php-devel ・yum-util
インストールが完了したら、一度「gdb」コマンドを入力し実行してみます。
すると、「Missing separate debuginfos, use: debuginfo-install ・・・・」とのメッセージがでました。。。
そんな時は、「use:」以降をコピーしてdebuginfoのパッケージをインストールします。
※ quit or q(quitの省略)でgdbから抜けます
ここまで出来たらサンプルプログラムを作成します。
とにかく「segmentation fault」というエラーを何でもいいので出したい・・・!!
どうしたら出せるだろうかと調べに調べた結果、とても簡単なことで出ることがわかりました。
<?php function test() { test(); } test(); ?>
ただ自分自身を呼び続けるだけ。。。。
そして、
今回は「cronでプログラムを実行したときに発生」という条件がありました。
httpdやphpのみでデバッグするときは
・service httpd stop ← apacheを停止 ・ulimit -c unlimited コマンドを実行 ← プロセスがファイルへコア・ダンプする容量を解除(unlimitedは無制限) ・gdb /usr/sbin/httpd コマンドを実行 ・gdb内で run -X を実行してapacheを起動 ・そして該当プログラムを実行させる(今回は上記サンプルプログラム)
cronの場合は出てこなかったのです。なぜ??
「ulimit」で設定するところがダメだったみたいです。
cronの場合は「/etc/security/limits.conf」の設定を見に行くみたいです。
なので、「/etc/security/limits.conf」に設定を追加
* soft core unlimited * hard core unlimited
そしてcronを再起動する。(service crond stop , start)
すると、coreファイルが作成されました!
core.8398(PID)
ちなみに、/proc/sys/kernel/core_patternを編集してcoreファイルのファイル名をフォーマットすることができます。
フォーマット例) /tmp/core.%e.%p ※%eは実行ファイル名(php ならphpとなる) ※%pはPID
そのcoreファイルをもとにgdbでデバッグをしてみる。
・gdb [出力されたcoreファイルの実行プログラム名] [出力されたcoreファイル] ← コマンドを実行 ・gdb内で「 print (char *)executor_globals.active_op_array->filename 」を実行する ← 該当ファイル名が表示される・・・! ・gdb内で「 print executor_globals.current_execute_data.opline->lineno 」を実行する ← 該当する行数が表示される・・・!
これで発生個所の特定ができました・・・!
エラー原因はサンプルプログラムを見ればわかりますが、
「segmentation fault」の発生個所を特定できました。
初めてのcore dump、色々知らないことばかりでしたので発生個所の特定ができた瞬間、
うれしくて興奮しすぎて、帰ってから一人カラオケで落ち着かせました。
そのくらい、うれしかったです。。。。