设为首页 - 加入收藏 - 网站地图 欢迎加QQ群 :14364084
当前位置:谭博的博客 > 编程语言 > php > 正文

更简单的重现PHP Core的调用栈

时间:2014-08-26 18:41 来源:未知 标签: 作者:谭博 阅读:

HP 5.4发生Core时, 包括参数的函数调用栈的信息.

假设对于如下的脚本:


  1. <?php
  2.  
  3. class Test {
  4. }
  5.  
  6. function a($i) {
  7.     b(new Test, 2.3432, "reader");
  8. }
  9. function b($i) {
  10.     c(array(1,2,3));
  11. }
  12. function c($i) {
  13.     d(TRUE);
  14. }
  15. function d($i) {
  16.     $fp = fopen("/tmp/1.php", "r");
  17.     e($fp);
  18. }
  19.  
  20. function e($i) {
  21.     sleep(1000);
  22. }
  23.  
  24. a();

使用后台运行以后, PHP5.4会sleep在e函数的sleep中, 这时, 如果我们使用gdb attach上去,


  1. gdb --pid= xxx //使用ps获得后台运行脚本的pid

然后, source PHP源代码下面的.gdbinit:


  1. (gdb) source php54-src/.gdbinit

然后, 让我们尝试调用下zbacktrace, 看看什么结果:


  1. (gdb) zbacktrace
  2. [0x2a95dac5e0] sleep(1000) /tmp/1.php:21
  3. [0x2a95dac4c0] e(resource(#5)) /tmp/1.php:17
  4. [0x2a95dac3f0] d(true) /tmp/1.php:13
  5. [0x2a95dac300] c(array(3)[0x2a95de7db0]) /tmp/1.php:10
  6. [0x2a95dac1c0] b(object[0x2a95de7840], 2.343200, "reader") /tmp/1.php:7
  7. [0x2a95dac0e8] a() /tmp/1.php:24

恩, 对于array和object, 因为我们为了保持不要乱屏, 所以没有展开, 不过, 如果我们要查看这个array具体是什么元素, 可以这样做, 注意到上面的:array(3)[0x2a95de7db0]:


  1. (gdb) print ((zval *)0x2a95de7db0)
  2. $4 = (struct _zval_struct *) 0x2a95de7db0
  3. (gdb) printzv $4
  4. [0x2a95de7db0] (refcount=2) array(3): {
  5.     0 => [0x2a95de79d0] (refcount=1) long: 1
  6.     1 => [0x2a95de7b80] (refcount=1) long: 2
  7.     2 => [0x2a95de7c98] (refcount=1) long: 3
  8.   }

类似的, 对于object, 注意到上面的: object[0x2a95de7840]


  1. (gdb) print ((zval *)0x2a95de7840)
  2. $5 = (struct _zval_struct *) 0x2a95de7840
  3. (gdb) printzv $5
  4. [0x2a95de7840] (refcount=2) object
  5. (Test) #1"no properties found"

要注意的一点是, 对于object, 如果你是在调式Core文件, 而不是attach到一个运行的进程上, 那么上面的尝试会得到一个错误:


  1. (gdb) printzv $5
  2. [0x2a95de7840] (refcount=2) objectYou can't do that without a process to debug.

不过, 即使这样, 我们还是有办法, 只不过就比较麻烦了.在NTS下面:


  1. (gdb) p ((zval *)0x2a95de7840)->value.obj.handle
  2. $6 = 1
  3. //注意, 下面用到了这个$6的值:1
  4. (gdb) p (zend_object*) executor_globals->objects_store.object_buckets[1].bucket.obj.object
  5. $7 = (struct _zend_object *) 0x2a95de3ec0
  6. (gdb) p $9->ce->name
  7. $8 = 0x2a95e200b0 "Test"
  8.  

 

关注微信公众号

微信扫一扫,打赏我

热评文章
    内容不错,支持一下
    评论列表(网友评论仅供网友表达个人看法,并不表明本站同意其观点或证实其描述)