what is php doing.

有些时候,当你运行一个php脚本时,你可能想知道这个脚本到底在捣鼓什么。有些工具可以帮助你不停脚本弄清楚它。这些工具有些只能再linux上工作。

stace

第一个工具是stace。stace是一个可以追踪系统调用的工具。系统调用主要是php读写网络端口或者文件;也包括通过网络和域套接字读写数据库。strace也会显示其他的系统调用比如time。stace的使用方法:
strace -p <processid>
processid可以通过先执行
ps aux|grep php
,然后根绝cpu利用率等信息来猜。也可以直接将程序作为strace的参数运行
strace php yourscript.php
你可以限定输出只特定的系统调用。使用如下命令讲只显示open和close系统调用。
strace -e open,close php yourscript.php
如果yourscript.php不存在,最后调用的输出如下:
...
open("/lib/x86_64-linux-gnu/libnss_files.so.2", O_RDONLY) = 3
close(3)                                = 0
open("/etc/services", O_RDONLY|O_CLOEXEC) = 3
close(3)                                = 0
open("/sys/devices/system/cpu", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 3
close(3)                                = 0
open("yourscript.php", O_RDONLY)        = -1 ENOENT (No such file or directory)
Could not open input file: yourscript.php
这个命令也有助于确定载入的是哪个php.ini
strace -e open php yourscript.php 2>&1 | grep php.ini
因为可能需要去stderr中提取信息,因此把stderr重定向到stdout

ltrace

ltrace的运行和使用与strace一样,它也能告诉你哪个内部库函数被调用了。它提供了更多的信息,但是它应该描述的更清楚点到底哪个C-library函数被调用,因此不如strace有用。

gdb

如果strace和ltrace都不能得到任何输出,可能你的脚本或者扩展正在做大量的计算。为了弄清楚到底哪个php函数被调用,你可以使用gdb工具。
gdb-the gnu debugger-是一个C/C++程序debugger。而且它提供了和Xdebug一样的php脚本debug功能。你可以将php脚本作为gdb的参数,然后在gdb命令行中输入run:
gdb --args php yourscript.php
(gdb) run

或者讲一个已经运行的进程作为参数,执行cont
gdb -p <processid>
(gdb) cont

一旦脚本运行到某个你感兴趣的状态想知道它到底在干什么,你可以ctrl-c. 这样你可以返回(gdb)提示符,然后可以输入运行bt得到php正在调用的C语言函数。例如:
^C
Program received signal SIGINT, Interrupt.
xdebug_execute (op_array=0x1f03b00)
        at /home/derick/dev/php/xdebug/xdebug.c:1409
1409                    zval_ptr_dtor(EG(return_value_ptr_ptr));
(gdb) bt
#0  xdebug_execute (op_array=0x1f03b00)
        at /home/derick/dev/php/xdebug/xdebug.c:1409
#1  0x000000000099d9a2 in zend_do_fcall_common_helper_SPEC (
        execute_data=0x7f3dec906090)
        at /home/derick/dev/php/php-src-git/branches/PHP_5_3/Zend/zend_vm_execute.h:344
#2  0x00000000009a1cb7 in ZEND_DO_FCALL_SPEC_CONST_HANDLER (
        execute_data=0x7f3dec906090)
        at /home/derick/dev/php/php-src-git/branches/PHP_5_3/Zend/zend_vm_execute.h:1640
#3  0x000000000099cce7 in execute (op_array=0x1ee2d50)
        at /home/derick/dev/php/php-src-git/branches/PHP_5_3/Zend/zend_vm_execute.h:107
#4  0x00007f3de53debfe in xdebug_execute (op_array=0x1ee2d50)
        at /home/derick/dev/php/xdebug/xdebug.c:1391
#5  0x00000000009696a8 in zend_execute_scripts (type=8, retval=0x0,
        file_count=3)
        at /home/derick/dev/php/php-src-git/branches/PHP_5_3/Zend/zend.c:1236
#6  0x00000000008f296d in php_execute_script (primary_file=0x7fff9ad6d8b0)
        at /home/derick/dev/php/php-src-git/branches/PHP_5_3/main/main.c:2308
#7  0x0000000000a4b8b3 in main (argc=2, argv=0x7fff9ad6db48)
        at /home/derick/dev/php/php-src-git/branches/PHP_5_3/sapi/cli/php_cli.c:1189

为了弄清正在运行那个php函数,bt略微有点无力。对于每个内部函数和方法,你可以看到函数以zip_和zim_开头。但是用户定义函数只有一个执行函数列表。但是这样你也可以弄清楚哪个用户定义函数正在被运行。顺便说一下.gdbinit脚本。
这个脚本是php资源分布的一部分,处于资源树的最高级。因为我想加载这个文件,我必须拷贝这个文件到自己的主目录。gdb在其开始载入该文件,但是如果你想在特定脚本下载入该文件,你可以再(gdb)提示符:
(gdb) source /home/derick/dev/php/PHP_5_3/.gdbinit

如果随着脚本载入可以再(gdb)提示符下:
(gdb) zbacktrace
一下面这个脚本举例:
<?php
function addOne( &$i )
{
        $i++;
}


$i = 0;
while (true) {
        addOne( $i );
}
?>

执行zbacktrace,结果如下:
(gdb) zbacktrace
[0xec906090] addOne() /tmp/yourscript.php:9

zz from: http://derickrethans.nl/what-is-php-doing.html
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值