valgrind

1,编译php的时候,必须要带上–enable-debug选项。



2,禁用php的内存管理。



禁用Zend MM
Zend虚拟机使用了自己的程序来优化内存管理,因此,valgrind无法探测到大部分的内存问题。在使用valgrind执行php之前,你必须禁用Zend自带的内存管理器。禁用方式为将环境变量USE_ZEND_ALLOC设置成0。



export USE_ZEND_ALLOC=0
或者



setenv USE_ZEND_ALLOC 0
上述方式适用于php5.2及以上的版本。5.2之前的php需要在编译的时候带上–disable-zend-memory-manager选项。



使用共享扩展
为了能在valgrind中正确显示extension的内存堆栈,需要设置:



export ZEND_DONT_UNLOAD_MODULES=1
或者



setenv ZEND_DONT_UNLOAD_MODULES 1
该设置作用于PHP 5.3.11及之后的版本。



编者注:举例来说,如果不设置ZEND_DONT_UNLOAD_MODULES,valgrind可能会报告



$ valgrind –leak-check=full –show-reachable=yes php test.php

==25829== 8 bytes in 1 blocks are indirectly lost in loss record 2 of 21
==25829== at 0x4C25E84: ???
==25829== by 0xCE440DC: ???
==25829== by 0xCE44316: ???
==25829== by 0xCE44368: ???
==25829== by 0xCBEE55F: ???
==25829== by 0xCBD3F87: ???
==25829== by 0x949A85: zend_activate_modules (zend_API.c:2285)
==25829== by 0x8B5EBC: php_request_startup (main.c:1491)
==25829== by 0xA84F7B: main (php_cli.c:1356)

如果设置ZEND_DONT_UNLOAD_MODULES,则会显示如下



$ valgrind –leak-check=full –show-reachable=yes php test.php

==25824== 8 bytes in 1 blocks are still reachable in loss record 2 of 30
==25824== at 0x4C25E84: calloc (in /usr/lib/valgrind/vgpreload_memcheck.so)
==25824== by 0xCE440DC: event_base_priority_init (in /usr/lib/libevent-1.4.so.2.1.3)
==25824== by 0xCE44316: event_base_new (in /usr/lib/libevent-1.4.so.2.1.3)
==25824== by 0xCE44368: event_init (in /usr/lib/libevent-1.4.so.2.1.3)
==25824== by 0xCBEE55F: zm_activate_http_request_pool (http_request_pool_api.c:58)
==25824== by 0xCBD3F87: zm_activate_http (http.c:373)
==25824== by 0x949A85: zend_activate_modules (zend_API.c:2285)
==25824== by 0x8B5EBC: php_request_startup (main.c:1491)
==25824== by 0xA84F7B: main (php_cli.c:1356)

使用CLI,web server内建或者CGI方式来执行php
为了使php CLI/CGI生成valgrind日志,你需要用以下命令来执行:



valgrind –tool=memcheck –num-callers=30 –log-file=php.log /path/to/php-cli script.php
这样会将log输出到当前目录下的php.log文件中。



如果要检测web server内建的php,需要对CLI可执行文件使用适当的-S和-t参数。然后通过浏览器请求来执行,再看php.log中的valgrind错误。



通过valgrind执行PHP Apache module
如果你是静态编译php和apache,那么需要确保apache的bin没有在make install之后被分离,否则会丢失所需的调试信息。检测如下,执行/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
如果要针对apache的php mod来生成valgrind的检测报告,你需要在valgrind下运行apache:



valgrind –tool=memcheck –num-callers=30 –log-file=apache.log /usr/local/apache/bin/httpd -X
通过浏览器请求来访问,所有的内存错误都会输出到apache.log中。

https://www.cnblogs.com/driftcloudy/p/3313240.html
https://www.laruence.com/2013/08/14/2899.html



$valgrind –tool=memcheck –leak-check=full –show-reachable=yes php spl.php
https://repo.or.cz/valgrind.git
https://blog.csdn.net/linhx/article/details/8234696
https://www.valgrind.org/downloads/repository.html
https://www.valgrind.org/downloads/current.html



在mac os下的安装略有不同,特写此文以记之。



现在最新的版本是3.8.1



tar jxvf valgrind-3.8.1.tar.bz2
cd valgrind-3.8.1
./configure
sudo xcode-select -switch /Applications/Xcode.app/Contents/Developer
make
sudo make install



https://www.valgrind.org/downloads/old.html



Mac下valgrind的安装和使用



安装valgrind
首先通过以下脚本安装valgrind,当前最新版本是3.11.0,



curl -O http://valgrind.org/downloads/valgrind-3.11.0.tar.bz2
tar -xjvf valgrind-3.11.0.tar.bz2
cd valgrind-3.11.0
./configure
make
sudo make install
但是在make的过程中出现如下错误,



make[2]: ** No rule to make target /usr/include/mach/mach_vm.defs', needed by m_mach/mach_vmUser.c’. Stop.
make[1]: **
[install-recursive] Error 1
make: *** [install] Error 2
1
2
3
根据参考的博客,发现首先需要安装命令行工具脚本如下,



xcode-select –install
1
因为我的Mac是64位,所以需要将./configure改成如下脚本,之后再make,最后安装sudo make install,



./configure –disable-tls –enable-only64bit –build=amd64-darwin
make
sudo make install
1
2
3
valgrind使用
假设main.cpp包含如下程序,



#include “stdlib.h”



int main(void)
{
int *x = (int *)malloc(100 * sizeof(int));
x[0] = 0;



return 0; }


通过如下脚本进行编译,



g++ main.cpp -o main
1
之后通过如下脚本进行检测,发现如下图有400bytes的内存泄露,



valgrind –tool=memcheck –leak-check=full –show-reachable=yes ./main
1



如果将main.cpp程序改成如下形式,加上释放内存的代码,发现将没有内存泄露,



#include “stdlib.h”



int main(void)
{
int *x = (int *)malloc(100 * sizeof(int));
x[0] = 0;



free(x);
x = NULL;

return 0; }


http://www.thinksaas.cn/group/topic/347310/
http://blog.csdn.net/21aspnet/article/details/8172124



https://blog.csdn.net/lkj345/article/details/50913895?utm_source=blogxgwz1



https://blog.csdn.net/lkj345/article/details/50913895
https://blog.csdn.net/qq_33336155/article/details/52608383
https://www.cnblogs.com/qujingtongxiao/p/9901213.html


Category php