毎晩 cron ジョブから実行するスクリプトがあります。最近、スクリプトを開始して数分後に完全にフリーズし始めましたが、その理由がわかりません。これが Java の場合は、実行するだけkill -3 PID
で標準出力にスレッド ダンプが出力されます。実行中の PHP スクリプトで現在のスタック トレース (および理想的にはメモリ情報) のダンプを取得できる、PHP に相当するものはありますか?
6 に答える
あなたができる最善のことは、--enable-debug
中に使用して自分でPHPをコンパイルすることですconfigure
。それでもプロセスがハングする場合は、gdbといくつかのマクロを使用して、次の手順を使用してPHPレベルのスタックトレースを取得できます。
$ gdb -p $PHP_PID
(gdb) bt # Get a system-level stacktrace, might already give some info
(gdb) source /path/to/php-src/.gdbinit # Load some useful macros
(gdb) dump_bt executor_globals.current_execute_data
# Macro from PHP's .gbinit giving PHP stack trace
# If you for whatever reason are using a thread-safe PHP build you have to do this:
(gdb) ____executor_globals
(gdb) dump_bt $eg.current_execute_data
そして、先にデバッグします:-)
これが機能するためには、シンボル情報を含むPHPバイナリが必要であることに注意してください--enable-debug
。
pcntl_signal を使用した解決策があることに気付きました。私は自分で試したことはありません。ここにサンプルコードがあります。
https://secure.phabricator.com/D7797
function __phutil_signal_handler__($signal_number) {
$e = new Exception();
$pid = getmypid();
// Some phabricator daemons may not be attached to a terminal.
Filesystem::writeFile(
sys_get_temp_dir().'/phabricator_backtrace_'.$pid,
$e->getTraceAsString());
}
if (function_exists('pcntl_signal')) {
pcntl_signal(SIGHUP, '__phutil_signal_handler__');
}
はい。でバックトレースを取得できますdebug_backtrace
。また、必要な場合がありmemory_get_usage
ます。
最大ランタイムを超えた場合、PHP スクリプトはタイムアウトする必要があります。確かにそれで問題は解決します。壊れるのを待つだけで、スタック トレースが表示されます。
コード (または php.ini) に、最大ランタイムをゼロに設定して壊れないようにする何かがある可能性があると思います。それができた場合は、それを取り除きます (または、デフォルトが実際に小さすぎる場合は、非常に大きなタイムアウトに設定します)。
また、xDebug または同様のツールで実行してみてください。これにより、プログラムのコール ツリーを提供するプロファイラー トレースが得られ、IDE でコードをステップ実行することもできるので、正確に何が起こっているのか; そこに無限ループがある場合は、そこからすぐに識別できるはずです。