ID: 34156 Updated by: [EMAIL PROTECTED] Reported By: robert at rw-it dot net -Status: Critical +Status: Closed Bug Type: Scripting Engine problem Operating System: * PHP Version: 5CVS, 4CVS (2005-08-18) New Comment:
This bug has been fixed in CVS. Snapshots of the sources are packaged every three hours; this change will be in the next snapshot. You can grab the snapshot at http://snaps.php.net/. Thank you for the report, and for helping us make PHP better. Previous Comments: ------------------------------------------------------------------------ [2005-08-16 21:48:25] robert at rw-it dot net Here is a patch that solves the problem (against 4.4.0, I hope it survives being pasted into a textarea): --- zend_alloc.c0 Thu Apr 7 20:54:33 2005 +++ zend_alloc.c Tue Aug 16 19:36:52 2005 @@ -64,11 +64,11 @@ #define CHECK_MEMORY_LIMIT(s, rs) _CHECK_MEMORY_LIMIT(s, rs, NULL, 0) # endif -#define _CHECK_MEMORY_LIMIT(s, rs, file, lineno) { AG(allocated_memory) += rs;\ - if (AG(memory_limit)<AG(allocated_memory)) {\ - int php_mem_limit = AG(memory_limit); \ - if (EG(in_execution) && AG(memory_limit)+1048576 > AG(allocated_memory) - rs) { \ - AG(memory_limit) = AG(allocated_memory) + 1048576; \ +#define _CHECK_MEMORY_LIMIT(s, rs, file, lineno) { unsigned int php_alloc_mem = AG(allocated_memory) + rs; \ + if (AG(memory_limit)<php_alloc_mem) {\ + unsigned int php_mem_limit = AG(memory_limit); \ + if (EG(in_execution) && AG(memory_limit)+1048576 > AG(allocated_memory)) { \ + AG(memory_limit) = php_alloc_mem + 1048576; \ if (file) { \ zend_error(E_ERROR,"Allowed memory size of %d bytes exhausted at %s:%d (tried to allocate %d bytes)", php_mem_limit, file, lineno, s); \ } else { \ @@ -83,6 +83,7 @@ exit(1); \ } \ } \ + AG(allocated_memory) = php_alloc_mem; \ } # endif ------------------------------------------------------------------------ [2005-08-16 20:58:23] robert at rw-it dot net Description: ------------ If memory_limit is turned on, memory will be marked as allocated although it isn't, because the _CHECK_MEMORY_LIMIT macro (zend_alloc.c) starts like this: #define _CHECK_MEMORY_LIMIT(s, rs, file, lineno) { AG(allocated_memory) += rs;\ Thus, allocated_memory is increased by the block size, even though zend_error might be called. This seems to apply to PHP-5.0.4, too, but not tested (only looked at the code). Reproduce code: --------------- Write some script that consumes all available memory: for ($i = 0, $b = 'x'; ; $i++, $b .= $b) echo "$i, "; Reload a few times. Expected result: ---------------- Same output everytime, no exit(1). Output for memory_limit = 8M on my machine: Allowed memory size of 8388608 bytes exhausted (tried to allocate 4194305 bytes) Actual result: -------------- Available memory decreases with each reload, until finally AG(memory_limit)+1048576 < AG(allocated_memory) - rs and PHP exits. Output for memory_limit = 8M: Allowed memory size of 8388608 bytes exhausted (tried to allocate 4194305 bytes) Allowed memory size of 8388608 bytes exhausted (tried to allocate 2097153 bytes) ... Allowed memory size of 8388608 bytes exhausted (tried to allocate 2049 bytes) (Server process exits on next reload) ------------------------------------------------------------------------ -- Edit this bug report at http://bugs.php.net/?id=34156&edit=1