IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者

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

风雪之隅 2011-12-11 16:05:24 累计浏览 3,143 次
本机暂存

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

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

假设对于如下的脚本:

<?php class Test {} function a($i) {    b(new Test, 2.3432, "reader");}function b($i) {    c(array(1,2,3));}function c($i) {    d(TRUE);}function d($i) {    $fp = fopen("/tmp/1.php", "r");    e($fp);} function e($i) {    sleep(1000);} a();

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

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

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

(gdb) source php54-src/.gdbini

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

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

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

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

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

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

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

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

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

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

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

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

同分类推荐文章

  1. 等了十年的 Go 链式管道,终于来了:seq 让你像写 Scala 一样写 Go (2026-06-25 18:38:18)
  2. Go 实验特性详解 (2026-06-21 10:05:27)
  3. amd64 微架构级别对 Go 程序性能提升多少? (2026-06-21 09:38:49)

查看更多 后端 文章 →

建议继续学习

  1. 使用gettext来支持PHP的多语言 (累计阅读 39,270)
  2. WordPress插件开发 -- 在插件使用数据库存储数据 (累计阅读 29,164)
  3. Paypal接口详细代码(PHP版,非API接口) (累计阅读 19,408)
  4. 调试工具之GDB (累计阅读 14,830)
  5. 我的PHP,Python和Ruby之路 (累计阅读 13,147)
  6. include(“./file.php”)和include(“file.php”)区别 (累计阅读 12,789)
  7. 15个最好的免费开源电子商务平台 (累计阅读 12,541)
  8. Redis消息队列的若干实现方式 (累计阅读 12,088)
  9. 到底什么是MVC? (累计阅读 11,866)
  10. 整理了一份招PHP高级工程师的面试题 (累计阅读 11,708)