|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2010-06-22 13:30 UTC] taco at procurios dot nl
Description: ------------ I've rewritten some create_function() calls to lambda functions. After updating our servers with the new code the following error started to occur on one of the servers: "Base lambda function for closure not found" We immediately replaced the new code with the old and tried to figure out what went wrong. Since we couldn't find the bug and on development machines nothing went wrong, we gave the new code another try: everything worked like expected, without errors. I'd really like to know what could have triggered this error, especially because we didn't change the code that triggered it. Patchestracing_modified_functions_classes.patch (last revision 2012-11-08 14:32 UTC by laruence@php.net)bug52144_new.patch (last revision 2012-11-07 10:58 UTC by laruence@php.net) autofilter_missing_funcs.patch (last revision 2012-11-03 14:59 UTC by gopalv@php.net) auto_filter_on_missing_lambdas.patch (last revision 2012-11-02 12:18 UTC by gopalv@php.net) bug52144.patch (last revision 2012-11-02 04:32 UTC by laruence@php.net) Pull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Sun Oct 26 21:00:01 2025 UTC |
The code in which the problem occurred looks like: <?php $methods = array( 'pfd_hor_pap' => function (&$v) { if (!empty($v)) { $v /= 13.66; } return true; }, // ...some other lambda functions ); // ...code that uses the array with lambda functions ?> The error occurs at the definition of the first lambda function in the array. The problem is that the error isn't reproducable (at least not when I want it to be). That's why I'd like to know what the typical situation is in which this error could occur.It seems option apc.write_lock=Off solves this problem partially. We have config with closure in style "<?php return array( ...., function() {...}, ... ); ?>" and include (not include_once) it seceral time per request. 1. If apc_cache_write_lock(apc_cache TSRMLS_CC) (apc_main.c:602) was unsuccessful at first include() then APC return old_compile_file. Function old_compile_file store compiled closures into internal zend hash function_table but not to cache. 2. If apc_cache_write_lock(apc_cache TSRMLS_CC) was successful at second include() then APC try to store opcode (apc_main.c:610-617), but function apc_copy_new_functions(apc_compile.c:1333,1340-1343) not found new functions (our closures) because zend hash function_table contains this closures already (closures were compiled at first include()). So APC copy compiled array from included file to cache without closures. 3. php-code try to call closure -> "Base lambda function for closure not found"We have spend many hours trying to reproduce this bug in our production environment and analyzing apc source code. There is more then one way to get this error in production, but in many cases you need to use load testing software or something to reproduce the bug. Here is the simple example that reproduces this bug. It is not the case in production systems but it is easy to reproduce and adresses absolutely the same problem. The root of the problem was explained here by s dot chernomorets at gmail dot com. You should create 3 scripts and put them in a directory under document root. Then make request to script1.php and click the link (or make request to script2.php) ======filename:lambda_function.php <? function() {} ?> ======filename:script1.php <?php apc_clear_cache(); ini_set('apc.cache_by_default', 0); include('lambda_function.php'); ini_set('apc.cache_by_default', 1); include('lambda_function.php'); ?> <a href="script2.php">CLICK TO REPRODUCE ERROR</a> ======filename:script2.php <?php include 'lambda_function.php';Just to weigh in and say we have just got bitten by the same bug. Suddenly started after an Apache restart. And another Apache restart fixed it. > PHP Fatal error: Base lambda function for closure not found in... The line reported in the error was the one that starts with "function" in the below code: <?php ... $connections = array_filter( $connections, function(SocialConnection $connection) use ($data) { return $connection->connected_mem_id == $data->mem_id; }); ... ?> php --version PHP 5.3.6-13ubuntu3.7 with Suhosin-Patch (cli) (built: May 4 2012 00:50:06) APC Version => 3.1.9 (from php -i | less)Hi, We meet the same error with the CMS Moodle. It is not easy to reproduce it because this bug occurs only sometimes. For me, it is when I use the administration search box. Here the server and software specs : Moodle 2.3.1 Ubuntu 10.04 Server LTS with APC cache 3.1.3p1 PHP 5.3.2-1ubuntu4.17 Apache/2.2.14 (Ubuntu) I got a blank page and in the apache log I got : PHP Fatal error: Base lambda function for closure not found in /var/www/moodle/mod/lti/settings.php on line 69 Here the line 69 : 69 $configuredtools = array_filter($types, function($value) { 70 return $value->state == LTI_TOOL_STATE_CONFIGURED; 71 }); I can still access the rest of Moodle fine, it's just the admin section that's broken during few minutes only. More information and other Moodle's users experience about it : http://moodle.org/mod/forum/discuss.php?d=199275 How can I help ?Actually, this is not a lambda specific issue, following test scripts will result a segfault(the similar reason): index.php: ---- <?php apc_clear_cache(); ini_set('apc.cache_by_default', 0); include('test.php'); ini_set('apc.cache_by_default', 1); include('test.php'); ?> <a href="seg.php">click here to segfault</a> ---- test.php ---- <?php if (!function_exists("test")) { function test() {} } ?> ---- seg.php ---- <?php include "test.php"; test(); ---- access the index.php, then click the link. segfault: (gdb) bt #0 0x00000000008b93a0 in do_bind_function (op_array=0x2b5fbe661100, opline=0x2b5fc2a315d8, function_table=0x1f36d000, compile_time=0 '\0') at /home/huixinchen/opensource/trunk/Zend/zend_compile.c:4510 #1 0x000000000091ebf2 in ZEND_DECLARE_FUNCTION_SPEC_HANDLER (execute_data=0x2b5fbe629310) at /home/huixinchen/opensource/trunk/Zend/zend_vm_execute.h:1098 #2 0x000000000091af12 in execute_ex (execute_data=0x2b5fbe629310) at /home/huixinchen/opensource/trunk/Zend/zend_vm_execute.h:440 #3 0x000000000091af8e in execute (op_array=0x2b5fbe65be70) at /home/huixinchen/opensource/trunk/Zend/zend_vm_execute.h:464 #4 0x00000000008dd589 in zend_execute_scripts (type=8, retval=0x0, file_count=3) at /home/huixinchen/opensource/trunk/Zend/zend.c:1309 #5 0x000000000084fee8 in php_execute_script (primary_file=0x7fffd6cc3a40) at /home/huixinchen/opensource/trunk/main/main.c:2468 .................Hey, I am not sure, if this is a *easy* test :) , access twice will trigger a segfault. <?php $is_second = apc_fetch("bug52144_accessed"); if (!$is_second) { $script = __DIR__ . "/script.inc"; if (!file_exists($script)) { file_put_contents(__DIR__ . "/script.inc", '<?php return function() {} ? >'); } apc_clear_cache(); ini_set("apc.cache_by_default", 0); include("script.inc"); ini_set("apc.cache_by_default", 1); include("script.inc"); apc_add("bug52144_accessed", true); } else { apc_delete("bug52144_accessed"); include("script.inc"); } ?>