更简单的重现PHP Core的调用栈
浏览:2171次 出处信息
以前, 我曾经介绍过如何通过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变得更好.
建议继续学习:
- 调试工具之GDB (阅读:13644)
- gdb的基本工作原理是什么? (阅读:10579)
- 深入理解Nginx之调试优化技巧 (阅读:6903)
- GDB中应该知道的几个调试方法 (阅读:5522)
- 使用GDB调试多进程程序 (阅读:5038)
- 使用gdb调试运行时的程序小技巧 (阅读:3751)
- 又一个PHP低概率Core的分析(PHP内存管理) (阅读:3430)
- GDB常用指令说明 (阅读:3090)
- GDB的两个技巧 (阅读:2600)
- 如何调试PHP的Core之获取基本信息 (阅读:2495)
QQ技术交流群:445447336,欢迎加入!
扫一扫订阅我的微信号:IT技术博客大学习
扫一扫订阅我的微信号:IT技术博客大学习
<< 前一篇:php抓取页面与代码解析
后一篇:PHP扩展开发:第一个扩展 >>
文章信息
- 作者:雪候鸟 来源: 风雪之隅
- 标签: core coredump gdb gdbinit
- 发布时间:2011-12-11 16:05:24
建议继续学习
近3天十大热文
- [70] Twitter/微博客的学习摘要
- [66] 如何拿下简短的域名
- [65] IOS安全–浅谈关于IOS加固的几种方法
- [64] find命令的一点注意事项
- [63] android 开发入门
- [63] Go Reflect 性能
- [61] 流程管理与用户研究
- [59] 图书馆的世界纪录
- [59] 读书笔记-壹百度:百度十年千倍的29条法则
- [59] Oracle MTS模式下 进程地址与会话信