Home >Backend Development >PHP Tutorial >Detecting PHP extension memory leaks with valgrind_PHP tutorial
Original text: https://bugs.php.net/bugs-getting-valgrind-log.php
1. When compiling php, you must bring --enable-debug选项
.
2. Disable php’s memory management.
The Zend virtual machine uses its own program to optimize memory management, so valgrind cannot detect most memory problems. Before using valgrind to execute php, you must disable Zend's own memory manager. To disable it, set the environment variable USE_ZEND_ALLOC to 0.
export USE_ZEND_ALLOC=0
or
setenv USE_ZEND_ALLOC 0
The above method is suitable for php5.2 and above versions. PHP before 5.2 needs to be compiled with the --disable-zend-memory-manager
option.
In order to correctly display the extension’s memory stack in valgrind, you need to set:
export ZEND_DONT_UNLOAD_MODULES=1
or
setenv ZEND_DONT_UNLOAD_MODULES 1
This setting applies to PHP 5.3.11 and later versions.
Editor's note: For example, if ZEND_DONT_UNLOAD_MODULES
is not set, valgrind may report
$ valgrind --leak-check=full --show-reachable=yes php test.php<br />...<br />==25829== 8 bytes in 1 blocks are indirectly lost in loss record 2 of 21<br />==25829== at 0x4C25E84: ???<br />==25829== by 0xCE440DC: ???<br />==25829== by 0xCE44316: ???<br />==25829== by 0xCE44368: ???<br />==25829== by 0xCBEE55F: ???<br />==25829== by 0xCBD3F87: ???<br />==25829== by 0x949A85: zend_activate_modules (zend_API.c:2285)<br />==25829== by 0x8B5EBC: php_request_startup (main.c:1491)<br />==25829== by 0xA84F7B: main (php_cli.c:1356)<br />...
If ZEND_DONT_UNLOAD_MODULES
is set, it will be displayed as follows
$ valgrind --leak-check=full --show-reachable=yes php test.php<br />...<br />==25824== 8 bytes in 1 blocks are still reachable in loss record 2 of 30<br />==25824== at 0x4C25E84: calloc (in /usr/lib/valgrind/vgpreload_memcheck.so)<br />==25824== by 0xCE440DC: event_base_priority_init (in /usr/lib/libevent-1.4.so.2.1.3)<br />==25824== by 0xCE44316: event_base_new (in /usr/lib/libevent-1.4.so.2.1.3)<br />==25824== by 0xCE44368: event_init (in /usr/lib/libevent-1.4.so.2.1.3)<br />==25824== by 0xCBEE55F: zm_activate_http_request_pool (http_request_pool_api.c:58)<br />==25824== by 0xCBD3F87: zm_activate_http (http.c:373)<br />==25824== by 0x949A85: zend_activate_modules (zend_API.c:2285)<br />==25824== by 0x8B5EBC: php_request_startup (main.c:1491)<br />==25824== by 0xA84F7B: main (php_cli.c:1356)<br />...
In order for php CLI/CGI to generate valgrind logs, you need to execute the following command:
valgrind --tool=memcheck --num-callers=30 --log-file=php.log /path/to/php-cli script.php
This will output the log to the php.log file in the current directory.
If you want to detect the php built into the web server, you need to use the appropriate -S and -t parameters for the CLI executable file. Then execute it through browser request, and then look at the valgrind error in php.log.
If you compile php and apache statically, you need to ensure that the apache bin is not separated after make install, otherwise the required debugging information will be lost. The detection is as follows, execute /path/to/httpd,这样会输出一些东西(例如not stripped)
$ file /usr/local/apache2/bin/httpd
/usr/local/apache2/bin/httpd: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), for GNU/Linux 2.6.4, dynamically linked (uses shared libs), not stripped
If you want to generate a valgrind detection report for apache's php mod, you need to run apache under valgrind:
valgrind --tool=memcheck --num-callers=30 --log-file=apache.log /usr/local/apache/bin/httpd -X
Accessed through browser requests, all memory errors will be output to apache.log.