- URL: https://www.laruence.com/en/2011/12/06/3206.html
- Please include attribution when republishing.
Previously, I introduced how to extract information from a PHP core file: Debugging a PHP core: getting basic information. As for the calling arguments, the method I described at the time was rather complex.
So today I made an improvement to the .gdbinit for PHP 5.4. Going forward, if you encounter a PHP 5.4 core, you can easily get the function call stack at the time of the core, including the arguments.
Consider the following script:
<?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();
After running it in the background, PHP 5.4 will be sleeping in the sleep() call of function e. At this point, if we attach gdb:
gdb --pid= xxx //get the pid of the background script via ps
Then source the .gdbinit under the PHP source tree:
(gdb) source php54-src/.gdbinit
Next, let's try calling zbacktrace and see what we get:
(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:24
Well, for arrays and objects we don't expand them by default, to keep the screen from filling up. But if we want to see what elements a particular array holds, we can do this. Note the above: 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
}
Similarly, for an object, note the above: object[0x2a95de7840]
(gdb) print ((zval *)0x2a95de7840) $5 = (struct _zval_struct *) 0x2a95de7840 (gdb) printzv $5 [0x2a95de7840] (refcount=2) object (Test) #1"no properties found"
One thing to note: for objects, if you are debugging a core file rather than attaching to a running process, the above attempt will produce an error:
(gdb) printzv $5 [0x2a95de7840] (refcount=2) objectYou can't do that without a process to debug.
But even so, there is still a way, just a more cumbersome one. Under NTS:
(gdb) p ((zval *)0x2a95de7840)->value.obj.handle $6 = 1 //note: the value of $6 (1) is used below (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"
Ha, so how's that? With this information, isn't analyzing the cause of a core a lot easier now? enjoy.
Finally, a reminder: PHP 5.4 is still under development. Before the final release, any new feature may be adjusted or changed. If you have any suggestions, feedback is welcome, to help make PHP even better.
Thanks
For more updates, follow: Changelog
Be First to Comment