There are a couple ways to debug php applications. We can enable core dump and/or install Xdebug.
Enable php core dump on php-fpm
First instruct the kernel to write core dumps to /tmp. On some system, dumps are fed to abrtd.
echo '/tmp/core-%e.%p' > /proc/sys/kernel/core_pattern
In php-fpm.conf, add the following
rlimit_core = unlimited
Restart php-fpm and use gdb to debug the dump files. To get the most out of the dump files, install the debuginfo packages for php and its extensions. e.g.
debuginfo-install php-fpm
Dump files can be examined with the following command. Be warned, the dump files can be severel hundred MiBs. It may fill up the filesystem quickly. Once a dump file is observed, core dump can be disabled by commenting out rlimit_core
in php-fpm.conf.
gdb /usr/sbin/php-fpm /tmp/core-file.1234
Install Xdebug
xdebug is really meant for php developers. But it also offer useful information for sysadmins. xdebug is available on most repositories. Once installed, it will write stack traces to php’s error log.
Enable php error log
# php.ini
error_log = /var/log/php.err
We can test this by doing a integer divide by zero error. Here is the php:
And this is logged:
[10-Jul-2018 22:05:13 Asia/Hong_Kong] PHP DivisionByZeroError: Division by zero in /sites/tools.headdesk.me/error.php on line 2
[10-Jul-2018 22:05:13 Asia/Hong_Kong] PHP Stack trace:
[10-Jul-2018 22:05:13 Asia/Hong_Kong] PHP 1. {main}() /sites/tools.headdesk.me/error.php:0
[10-Jul-2018 22:05:13 Asia/Hong_Kong] PHP 2. intdiv() /sites/tools.headdesk.me/error.php:2
[10-Jul-2018 22:05:13 Asia/Hong_Kong] PHP Fatal error: Uncaught DivisionByZeroError: Division by zero in /sites/tools.headdesk.me/error.php:2
Stack trace:
#0 /sites/tools.headdesk.me/error.php(2): intdiv(1, 0)
#1 {main}
thrown in /sites/tools.headdesk.me/error.php on line 2
Additionally, xdebug can profile php applications. The simplest way is to enable profile logs being written to the local filesystem. Then the file can be opened with debugclient or php IDEs. debugclient is bundled with xdebug in /usr/bin/debugclient
. This allows profiling without direct connection to xdebug. If you do have connection to the php environment, see remote profiling
xdebug.profiler_enable=1
xdebug.profiler_output_dir="/tmp"