|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2012-01-23 05:16 UTC] sean@php.net
Description: ------------ In testing my app against PHP 5.4.0RC6, I found that it would crash on the *second* request, within my front-end framework (which happens to be an old version of Lithium). I've tried to identify exactly what userspace code is causing this, and I've managed to distill it down to around 20 PHP files, but I can't get this to happen in a *small* use case. Nor will it happen from the command line. If I remove the APC extension, Apache does not crash. I've tested with APC 3.1.9 and also with APC from svn-trunk. Both crash. Here is the code I've boiled down: http://files.seancoates.com/apccrash-li3.tar.bz2 ; point your DocumentRoot at frontend/webroot/ I've run it through gdb and valgrind (thanks much to Rasmus for hand-holding). gdb: http://paste.roguecoders.com/p/a8769024952f7b616886ab5b06da358f.txt valgrind: http://paste.roguecoders.com/p/3cfd5c63ff22fd9c556e5ebc240a7044.txt I realize that "over-complicated" front-end code is part of the problem here, but even so, this app works on PHP 5.3, so something that changed is causing Apache (PHP with APC) to crash on 5.4. Note also that even after Lithium has caused PHP to crash, other non-Lithium code continues to work (such as apc.php, included). My gut tells me this is autoloader-related (Libraries.php), but I've been unable to narrow the actual test specifically to that. If there's anything else I can provide, I would be happy to do so. Please ask. If, for some reason others can't reproduce this problem with the code I've posted above, I could probably package up a VirtualBox VM that exhibits this problem. Test script: --------------- Plese see http://files.seancoates.com/apccrash-li3.tar.bz2 Expected result: ---------------- No crash Actual result: -------------- Crash on 2nd request PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Sat Oct 25 01:00:01 2025 UTC |
Found it (I think). The Libraries class (lithium/core/Libraries.php) contains a method called _params(). The first line of the method reads `$name = $name ?: "*";`, which ensures that empty values of `$name` are replaced with the default parameter value of the name parameter (method signature: `protected static function _params($type, $name = "*")`. If I (a) comment this line out (the conditional has no effect on the test code), or (b) rewrite it to a long-hand if block, i.e.: if (!$name) { $name = '*'; } ...the segfaulting goes away. If I uncomment it or replace it with the original, the segfaulting resumes, usually after 2 or 3 refreshes (I was testing in Chrome, so it probably does some stupidly-aggressive caching).I've put together a small test that seems to be enough to consistently reproduce the crash: <?php function bar($type, $name = "Bob") { $name = $name ?: "Bob"; echo $name; } bar("Foo!"); ?> To mitigate the browser caching issues, I started testing with wget, and noticed that after the APC cache was primed (which of course caused PHP to segfault and return no data), wget would retry 3 times immediately, then wait 5 seconds and retry again. This is where it gets weirder. The first 4 requests would segfault and return no data. The final request (after the 5- second delay) wouldn't segfault, but always returned the same corrupt data. This pattern was repeatable consistently over the 10 or so iterations I tried.Well done, Nate. I can confirm that switching the ?: to the longhand form keeps my large test case from crashing, and additionally, I can confirm that the above small test case crashes on 5.4.0RC7 for me. Here is a slightly smaller test case. <?php // DOES CRASH: function bar() { $name = true; $name = $name ?: "Bob"; echo $name; } bar(); ?> <?php // DOES NOT CRASH: function bar() { $name = null; $name = $name ?: "Bob"; echo $name; } bar(); ?> Also, without the function context/wrapper, the crashy code above does not crash. S