|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2005-08-16 20:58 UTC] 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)
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Tue Oct 28 14:00:01 2025 UTC |
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