以前, 我曾经介绍过如何通过PHP的Core文件获取信息:如何调试PHP的Core之获取基本信息, 对于调用参数这块, 当时介绍的获取方法比较复杂.

于是今天我为PHP 5.4的.gdbinit做了一个改进, 以后如果你遇到了PHP 5.4的core, 那么就可以简单的得到PHP 5.4发生Core时, 包括参数的函数调用栈的信息.

假设对于如下的脚本:

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

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

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

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

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

然后, 让我们尝试调用下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:2

恩, 对于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

类似的, 对于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

呵呵, 怎么样, 有了这些信息, 分析Core的原因, 是不是就更简单了呢? enjoy~

最后, 还是要提醒下: PHP 5.4还处于开发阶段, 在最终release之前, 任何新特性都可能被调整或者更改. 如果大家有任何建议, 也欢迎反馈, 帮助我们使得PHP变得更好

重现PHP Core的调用栈的更多相关文章

  1. Linux下手动获取当前调用栈

    被问到如何手动获取当前的调用栈,之前碰到过一时没记起来,现在回头整理一下. 其原理是:使用backtrace()从栈中获取当前调用各层函数调用的返回地址,backtrace_symbols()将对应地 ...

  2. arm平台的调用栈回溯(backtrace)

    title: arm平台的调用栈回溯(backtrace) date: 2018-09-19 16:07:47 tags: --- 介绍 arm平台的调用栈与x86平台的调用栈大致相同,稍微有些区别, ...

  3. 获取崩溃时的调用栈和生成dump文件,然后自动重启

    首先要说明的是:  linux 下 比较方便可以得到 崩溃时的调用栈,win下 比较难办   1. linux 获取调用栈 代码奉上: #include <execinfo.h> //在头 ...

  4. JavaScript是如何工作的:引擎,运行时间以及调用栈的概述

    JavaScript是如何工作的:引擎,运行时以及调用栈的概述 原文:How JavaScript works: an overview of the engine, the runtime, and ...

  5. 在c或c+程序里打印调用栈。转

    在C/C++程序里打印调用栈信息 我们知道,GDB的backtrace命令可以查看堆栈信息.但很多时候,GDB根本用不上.比如说,在线上环境中可能没有GDB,即使有,也不太可能让我们直接在上面调试.如 ...

  6. 在C/C++程序里打印调用栈信息

    我们知道,GDB的backtrace命令可以查看堆栈信息.但很多时候,GDB根本用不上.比如说,在线上环境中可能没有GDB,即使有,也不太可能让我们直接在上面调试.如果能让程序自己输出调用栈,那是最好 ...

  7. android打印调用栈

    在某些机器上,不能下断点,出现了某个诡异的问题,想到唯一的解决方式,就是打印调用栈了,google发现这个,记录下,以后备用 Log.d(",Log.getStackTraceString( ...

  8. Nagios Core/Icinga 基于栈的缓冲区溢出漏洞

    漏洞名称: Nagios Core/Icinga 基于栈的缓冲区溢出漏洞 CNNVD编号: CNNVD-201402-484 发布时间: 2014-03-03 更新时间: 2014-03-03 危害等 ...

  9. GDB 运行PYTHON 脚本+python 转换GDB调用栈到流程图

    http://tromey.com/blog/?cat=17 http://blog.csdn.net/cnsword/article/details/16337031 http://blog.csd ...

随机推荐

  1. apache开源项目--ZooKeeper

    ZooKeeper是Hadoop的正式子项目,它是一个针对大型分布式系统的可靠协调系统,提供的功能包括:配置维护.名字服务.分布式同步.组服务等.ZooKeeper的目标就是封装好复杂易出错的关键服务 ...

  2. [转] python程序的调试方法

    qi09 原文 python程序的调试方法 本文讨论在没有方便的IDE工具可用的情况下,使用pdb调试python程序 源码例子 例如,有模拟税收计算的程序: #!/usr/bin/python de ...

  3. 单实例运行tz

    (引用了 Microsoft.VisualBasic.ApplicationServices)SingleInstanceApplicationWrapper.cs    using System.W ...

  4. C# 两个ListBox 数据互传-基础操作

    先看效果图: 两个服务设施列,左边:lbFacility1,右边:lbFacility2,中间向左向右箭头. 如果只是单纯的向左向右移动,那很简单. 因为项目遇到要获取选中项的ID,通过给ListBo ...

  5. dynamips虚拟服务:找不到指定设备

    刚开始接触dynamips,属于新手, 之前是可以正常使用dynamips的,但不知道什么原因就出现这样的问题 果断重新安装,之后可以正常使用

  6. 自动脚本工具新版 v2.0

    自动脚本工具 下载 下载工具后,解压,直接双击 "execute.bat" 文件后(前提已配置好 jdk 1.7 的环境),会生成文件夹 "output",该文 ...

  7. CPU的ADDR2为什么跟SDRAM的0地址线接在一起

    出处:http://www.100ask.org/bbs/forum.php?mod=viewthread&tid=11544&fromuid=5490 最近看到坛子里很多初学者对于C ...

  8. 谈谈Nginx有哪些特点

    1.热部署        我个人觉得这个很不错.在master管理进程与worker工作进程的分离设计,使的Nginx具有热部署的功能,那么在7×24小时不间断服务的前提下,升级Nginx的可执行文件 ...

  9. HDU-4639 Hehe 简单DP

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4639 简单递推题,呵呵,不多说... //STATUS:C++_AC_15MS_272KB #incl ...

  10. adb不响应

    1.CMD命令窗口输入:adb nodaemon server .然后就会提示你哪个端口被占用了. 2.输入netstat -ano | findstr "5037" .然后会弹出 ...