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

Reply via email to