Skip to content

Commit 2209c1a

Browse files
committed
Fix the attempted allocation size in OOM error messages
The sizes reported in the error messages previously didn't match the sizes that were actually checked against the memory limit. This can result in confusing error reports, because the reported size often tends to be much smaller than the actual chunk allocation size used in accounting. Consider the following example script: <?php $foo = []; while (true) { var_dump(memory_get_usage()); $foo[] = new stdClass(); } Executing the script as sapi/cli/php -dmemory_limit=5145728 oom.php results in: int(3833360) int(3833440) int(3833520) Fatal error: Allowed memory size of 5145728 bytes exhausted at php-src/Zend/zend_objects_API.c:136 (tried to allocate 524320 bytes) in php-src/oom.php on line 5 With each iteration the actual memory usage grows by 80 bytes. The error message reports roughly 512 KiB of additional usage, possibly for an array resizing, but even for those additional 512 KiB the last observed memory usage does not exceed the memory limit of 5145728 Bytes. This is because actually a chunk of 2 MiB is going to be allocated and that is what is checked. The following output was created with this patch applied: int(3833360) int(3833440) int(3833520) Fatal error: Allowed memory size of 5145728 bytes exhausted at php-src/Zend/zend_objects_API.c:136 (tried to allocate 2097152 bytes) in php-src/oom.php on line 5 With the fixed output the attempted allocation clearly exceeds the memory limit. In a further change the error message could possibly be adjusted to also report the current memory usage instead of just the limit + the attempted allocation.
1 parent 42a85fc commit 2209c1a

File tree

1 file changed

+10
-10
lines changed

1 file changed

+10
-10
lines changed

Zend/zend_alloc.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1010,9 +1010,9 @@ static void *zend_mm_alloc_pages(zend_mm_heap *heap, uint32_t pages_count ZEND_F
10101010
goto get_chunk;
10111011
} else if (heap->overflow == 0) {
10121012
#if ZEND_DEBUG
1013-
zend_mm_safe_error(heap, "Allowed memory size of %zu bytes exhausted at %s:%d (tried to allocate %zu bytes)", heap->limit, __zend_filename, __zend_lineno, size);
1013+
zend_mm_safe_error(heap, "Allowed memory size of %zu bytes exhausted at %s:%d (tried to allocate %zu bytes)", heap->limit, __zend_filename, __zend_lineno, ZEND_MM_CHUNK_SIZE);
10141014
#else
1015-
zend_mm_safe_error(heap, "Allowed memory size of %zu bytes exhausted (tried to allocate %zu bytes)", heap->limit, ZEND_MM_PAGE_SIZE * pages_count);
1015+
zend_mm_safe_error(heap, "Allowed memory size of %zu bytes exhausted (tried to allocate %zu bytes)", heap->limit, ZEND_MM_CHUNK_SIZE);
10161016
#endif
10171017
return NULL;
10181018
}
@@ -1028,9 +1028,9 @@ static void *zend_mm_alloc_pages(zend_mm_heap *heap, uint32_t pages_count ZEND_F
10281028
#if !ZEND_MM_LIMIT
10291029
zend_mm_safe_error(heap, "Out of memory");
10301030
#elif ZEND_DEBUG
1031-
zend_mm_safe_error(heap, "Out of memory (allocated %zu bytes) at %s:%d (tried to allocate %zu bytes)", heap->real_size, __zend_filename, __zend_lineno, size);
1031+
zend_mm_safe_error(heap, "Out of memory (allocated %zu bytes) at %s:%d (tried to allocate %zu bytes)", heap->real_size, __zend_filename, __zend_lineno, ZEND_MM_CHUNK_SIZE);
10321032
#else
1033-
zend_mm_safe_error(heap, "Out of memory (allocated %zu bytes) (tried to allocate %zu bytes)", heap->real_size, ZEND_MM_PAGE_SIZE * pages_count);
1033+
zend_mm_safe_error(heap, "Out of memory (allocated %zu bytes) (tried to allocate %zu bytes)", heap->real_size, ZEND_MM_CHUNK_SIZE);
10341034
#endif
10351035
return NULL;
10361036
}
@@ -1536,9 +1536,9 @@ static zend_never_inline void *zend_mm_realloc_huge(zend_mm_heap *heap, void *pt
15361536
/* pass */
15371537
} else if (heap->overflow == 0) {
15381538
#if ZEND_DEBUG
1539-
zend_mm_safe_error(heap, "Allowed memory size of %zu bytes exhausted at %s:%d (tried to allocate %zu bytes)", heap->limit, __zend_filename, __zend_lineno, size);
1539+
zend_mm_safe_error(heap, "Allowed memory size of %zu bytes exhausted at %s:%d (tried to allocate %zu bytes)", heap->limit, __zend_filename, __zend_lineno, (new_size - old_size));
15401540
#else
1541-
zend_mm_safe_error(heap, "Allowed memory size of %zu bytes exhausted (tried to allocate %zu bytes)", heap->limit, size);
1541+
zend_mm_safe_error(heap, "Allowed memory size of %zu bytes exhausted (tried to allocate %zu bytes)", heap->limit, (new_size - old_size));
15421542
#endif
15431543
return NULL;
15441544
}
@@ -1828,9 +1828,9 @@ static void *zend_mm_alloc_huge(zend_mm_heap *heap, size_t size ZEND_FILE_LINE_D
18281828
/* pass */
18291829
} else if (heap->overflow == 0) {
18301830
#if ZEND_DEBUG
1831-
zend_mm_safe_error(heap, "Allowed memory size of %zu bytes exhausted at %s:%d (tried to allocate %zu bytes)", heap->limit, __zend_filename, __zend_lineno, size);
1831+
zend_mm_safe_error(heap, "Allowed memory size of %zu bytes exhausted at %s:%d (tried to allocate %zu bytes)", heap->limit, __zend_filename, __zend_lineno, new_size);
18321832
#else
1833-
zend_mm_safe_error(heap, "Allowed memory size of %zu bytes exhausted (tried to allocate %zu bytes)", heap->limit, size);
1833+
zend_mm_safe_error(heap, "Allowed memory size of %zu bytes exhausted (tried to allocate %zu bytes)", heap->limit, new_size);
18341834
#endif
18351835
return NULL;
18361836
}
@@ -1846,9 +1846,9 @@ static void *zend_mm_alloc_huge(zend_mm_heap *heap, size_t size ZEND_FILE_LINE_D
18461846
#if !ZEND_MM_LIMIT
18471847
zend_mm_safe_error(heap, "Out of memory");
18481848
#elif ZEND_DEBUG
1849-
zend_mm_safe_error(heap, "Out of memory (allocated %zu bytes) at %s:%d (tried to allocate %zu bytes)", heap->real_size, __zend_filename, __zend_lineno, size);
1849+
zend_mm_safe_error(heap, "Out of memory (allocated %zu bytes) at %s:%d (tried to allocate %zu bytes)", heap->real_size, __zend_filename, __zend_lineno, new_size);
18501850
#else
1851-
zend_mm_safe_error(heap, "Out of memory (allocated %zu bytes) (tried to allocate %zu bytes)", heap->real_size, size);
1851+
zend_mm_safe_error(heap, "Out of memory (allocated %zu bytes) (tried to allocate %zu bytes)", heap->real_size, new_size);
18521852
#endif
18531853
return NULL;
18541854
}

0 commit comments

Comments
 (0)