Skip to content

Fix the attempted allocation size in OOM error messages #11763

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Zend/tests/bug40770.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@ for ($i=0; $i<=$mb; $i++) {
}
?>
--EXPECTF--
Fatal error: Allowed memory size of 8388608 bytes exhausted%s(tried to allocate %d bytes) in %s on line %d
Fatal error: Allowed memory size of %d bytes exhausted by %d bytes%S. Allocated %d bytes and need to allocate %d bytes to satisfy a reallocation from %d to %d bytes in %s on line %d
2 changes: 1 addition & 1 deletion Zend/tests/bug54268.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,4 @@ $x = new Test();
Test::$mystatic = new DestructorCreator();
?>
--EXPECTF--
Fatal error: Allowed memory size of %s bytes exhausted%s(tried to allocate %s bytes) in %s on line %d
Fatal error: Allowed memory size of %d bytes exhausted by %d bytes%S. Allocated %d bytes and need to allocate %d bytes to satisfy a request for %d bytes in %s on line %d
2 changes: 1 addition & 1 deletion Zend/tests/bug55509.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -78,4 +78,4 @@ echo "5\n";
3
4

Fatal error: Allowed memory size of %d bytes exhausted%s(tried to allocate %d bytes) in %sbug55509.php on line %d
Fatal error: Allowed memory size of %d bytes exhausted by %d bytes%S. Allocated %d bytes and need to allocate %d bytes in %s on line %d
2 changes: 1 addition & 1 deletion Zend/tests/bug70258.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,4 @@ $a = new A;
$a->core();
?>
--EXPECTF--
Fatal error: Allowed memory size of 2097152 bytes exhausted%s(tried to allocate %d bytes) in %s on line %d
Fatal error: Allowed memory size of %d bytes exhausted by %d bytes%S. Allocated %d bytes and need to allocate %d bytes to satisfy a request for %d bytes in %s on line %d
2 changes: 1 addition & 1 deletion Zend/tests/bug76846.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,4 @@ while (true) {

?>
--EXPECTF--
Fatal error: Allowed memory size of %d bytes exhausted%s(tried to allocate %d bytes) in %s on line %d%A
Fatal error: Allowed memory size of %d bytes exhausted by %d bytes%S. Allocated %d bytes and need to allocate %d bytes to satisfy a reallocation from %d to %d bytes in %s on line %d
2 changes: 1 addition & 1 deletion Zend/tests/bug79836_4.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ $e = new Foo();
$e .= $i;
?>
--EXPECTF--
Fatal error: Allowed memory size of %d bytes exhausted%s(tried to allocate %d bytes) in %s on line %d
Fatal error: Allowed memory size of %d bytes exhausted by %d bytes%S. Allocated %d bytes and need to allocate %d bytes in %s on line %d
2 changes: 1 addition & 1 deletion Zend/tests/fibers/get-return-after-bailout.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ $fiber->start();

?>
--EXPECTF--
Fatal error: Allowed memory size of %d bytes exhausted%s(tried to allocate %d bytes) %sget-return-after-bailout.php on line %d
Fatal error: Allowed memory size of %d bytes exhausted by %d bytes%S. Allocated %d bytes and need to allocate %d bytes in %s on line %d

Fatal error: Uncaught FiberError: Cannot get fiber return value: The fiber exited with a fatal error in %sget-return-after-bailout.php:%d
Stack trace:
Expand Down
2 changes: 1 addition & 1 deletion Zend/tests/fibers/out-of-memory-in-fiber.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@ $fiber->start();

?>
--EXPECTF--
Fatal error: Allowed memory size of %d bytes exhausted%s(tried to allocate %d bytes) in %sout-of-memory-in-fiber.php on line %d
Fatal error: Allowed memory size of %d bytes exhausted by %d bytes%S. Allocated %d bytes and need to allocate %d bytes to satisfy a request for %d bytes in %s on line %d
2 changes: 1 addition & 1 deletion Zend/tests/fibers/out-of-memory-in-nested-fiber.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,4 @@ $fiber->start();

?>
--EXPECTF--
Fatal error: Allowed memory size of %d bytes exhausted%s(tried to allocate %d bytes) in %sout-of-memory-in-nested-fiber.php on line %d
Fatal error: Allowed memory size of %d bytes exhausted by %d bytes%S. Allocated %d bytes and need to allocate %d bytes to satisfy a request for %d bytes in %s on line %d
2 changes: 1 addition & 1 deletion Zend/tests/fibers/out-of-memory-in-recursive-fiber.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,4 @@ $fiber->start();

?>
--EXPECTF--
Fatal error: Allowed memory size of %d bytes exhausted%s(tried to allocate %d bytes) in %sout-of-memory-in-recursive-fiber.php on line %d
Fatal error: Allowed memory size of %d bytes exhausted by %d bytes%S. Allocated %d bytes and need to allocate %d bytes to satisfy a request for %d bytes in %s on line %d
2 changes: 1 addition & 1 deletion Zend/tests/gh11189.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,4 @@ while (1) {
?>
--EXPECTF--
Success
Fatal error: Allowed memory size of %s bytes exhausted%s(tried to allocate %s bytes) in %s on line %d
Fatal error: Allowed memory size of %d bytes exhausted by %d bytes%S. Allocated %d bytes and need to allocate %d bytes in %s on line %d
2 changes: 1 addition & 1 deletion Zend/tests/gh11189_1.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,4 @@ while (1) {
?>
--EXPECTF--
Success
Fatal error: Allowed memory size of %s bytes exhausted%s(tried to allocate %s bytes) in %s on line %d
Fatal error: Allowed memory size of %d bytes exhausted by %d bytes%S. Allocated %d bytes and need to allocate %d bytes to satisfy a request for %d bytes in %s on line %d
2 changes: 1 addition & 1 deletion Zend/tests/gh12073.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,4 @@ for ($i = 0; $i < 10_000; $i++) {

?>
--EXPECTF--
Fatal error: Allowed memory size of %d bytes exhausted%s(tried to allocate %d bytes) in %s on line %d
Fatal error: Allowed memory size of %d bytes exhausted by %d bytes%S. Allocated %d bytes and need to allocate %d bytes to satisfy a request for %d bytes in %s on line %d
2 changes: 1 addition & 1 deletion Zend/tests/new_oom.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ $php = PHP_BINARY;

foreach (get_declared_classes() as $class) {
$output = shell_exec("$php --no-php-ini $file $class 2>&1");
if ($output && preg_match('(^\nFatal error: Allowed memory size of [0-9]+ bytes exhausted[^\r\n]* \(tried to allocate [0-9]+ bytes\) in [^\r\n]+ on line [0-9]+$)', $output) !== 1) {
if ($output && preg_match('(^\nFatal error: Allowed memory size of [0-9]+ bytes exhausted by [0-9]+ bytes[^\r\n]*. Allocated [0-9]+ bytes and need to allocate [0-9]+ bytes to satisfy a request for [0-9]+ bytes in [^\r\n]+ on line [0-9]+$)', $output) !== 1) {
echo "Class $class failed\n";
echo $output, "\n";
}
Expand Down
117 changes: 73 additions & 44 deletions Zend/zend_alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -368,26 +368,17 @@ static ZEND_COLD ZEND_NORETURN void zend_mm_panic(const char *message)
abort();
}

static ZEND_COLD ZEND_NORETURN void zend_mm_safe_error(zend_mm_heap *heap,
const char *format,
size_t limit,
#if ZEND_DEBUG
const char *filename,
uint32_t lineno,
#endif
size_t size)
static ZEND_COLD ZEND_NORETURN void zend_mm_safe_error(zend_mm_heap *heap, char* format, ...)
{
va_list args;

heap->overflow = 1;
zend_try {
zend_error_noreturn(E_ERROR,
format,
limit,
#if ZEND_DEBUG
filename,
lineno,
#endif
size);
va_start(args, format);
zend_string *message = zend_vstrpprintf(0, format, args);
zend_error_noreturn(E_ERROR, "%s", ZSTR_VAL(message));
zend_string_release(message);
va_end(args);
} zend_catch {
} zend_end_try();
heap->overflow = 0;
Expand Down Expand Up @@ -1009,11 +1000,26 @@ static void *zend_mm_alloc_pages(zend_mm_heap *heap, uint32_t pages_count ZEND_F
if (zend_mm_gc(heap)) {
goto get_chunk;
} else if (heap->overflow == 0) {
#if ZEND_DEBUG
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);
#else
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);
#endif
zend_mm_safe_error(
heap,
"Allowed memory size of %zu bytes exhausted by %zu bytes"
# if ZEND_DEBUG
" at %s:%d"
# endif
". Allocated %zu bytes and need to allocate %zu bytes to satisfy a request for %zu bytes",

heap->limit, (ZEND_MM_CHUNK_SIZE - (heap->limit - heap->real_size)),
# if ZEND_DEBUG
__zend_filename, __zend_lineno,
# endif
heap->real_size, ZEND_MM_CHUNK_SIZE,
# if ZEND_DEBUG
size
# else
ZEND_MM_PAGE_SIZE * pages_count
# endif
);

return NULL;
}
}
Expand All @@ -1028,9 +1034,9 @@ static void *zend_mm_alloc_pages(zend_mm_heap *heap, uint32_t pages_count ZEND_F
#if !ZEND_MM_LIMIT
zend_mm_safe_error(heap, "Out of memory");
#elif ZEND_DEBUG
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);
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);
#else
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);
zend_mm_safe_error(heap, "Out of memory (allocated %zu bytes) (tried to allocate %zu bytes)", heap->real_size, ZEND_MM_CHUNK_SIZE);
#endif
return NULL;
}
Expand Down Expand Up @@ -1535,11 +1541,20 @@ static zend_never_inline void *zend_mm_realloc_huge(zend_mm_heap *heap, void *pt
if (zend_mm_gc(heap) && new_size - old_size <= heap->limit - heap->real_size) {
/* pass */
} else if (heap->overflow == 0) {
#if ZEND_DEBUG
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);
#else
zend_mm_safe_error(heap, "Allowed memory size of %zu bytes exhausted (tried to allocate %zu bytes)", heap->limit, size);
#endif
zend_mm_safe_error(
heap,
"Allowed memory size of %zu bytes exhausted by %zu bytes"
# if ZEND_DEBUG
" at %s:%d"
# endif
". Allocated %zu bytes and need to allocate %zu bytes to satisfy a reallocation from %zu to %zu bytes",

heap->limit, ((new_size - old_size) - (heap->limit - heap->real_size)),
# if ZEND_DEBUG
__zend_filename, __zend_lineno,
# endif
heap->real_size, (new_size - old_size), old_size, new_size
);
return NULL;
}
}
Expand Down Expand Up @@ -1827,11 +1842,20 @@ static void *zend_mm_alloc_huge(zend_mm_heap *heap, size_t size ZEND_FILE_LINE_D
if (zend_mm_gc(heap) && new_size <= heap->limit - heap->real_size) {
/* pass */
} else if (heap->overflow == 0) {
#if ZEND_DEBUG
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);
#else
zend_mm_safe_error(heap, "Allowed memory size of %zu bytes exhausted (tried to allocate %zu bytes)", heap->limit, size);
#endif
zend_mm_safe_error(
heap,
"Allowed memory size of %zu bytes exhausted by %zu bytes"
# if ZEND_DEBUG
" at %s:%d"
# endif
". Allocated %zu bytes and need to allocate %zu bytes",

heap->limit, (new_size - (heap->limit - heap->real_size)),
# if ZEND_DEBUG
__zend_filename, __zend_lineno,
# endif
heap->real_size, new_size
);
return NULL;
}
}
Expand All @@ -1846,9 +1870,9 @@ static void *zend_mm_alloc_huge(zend_mm_heap *heap, size_t size ZEND_FILE_LINE_D
#if !ZEND_MM_LIMIT
zend_mm_safe_error(heap, "Out of memory");
#elif ZEND_DEBUG
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);
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);
#else
zend_mm_safe_error(heap, "Out of memory (allocated %zu bytes) (tried to allocate %zu bytes)", heap->real_size, size);
zend_mm_safe_error(heap, "Out of memory (allocated %zu bytes) (tried to allocate %zu bytes)", heap->real_size, new_size);
#endif
return NULL;
}
Expand Down Expand Up @@ -2823,15 +2847,20 @@ static zend_always_inline zval *tracked_get_size_zv(zend_mm_heap *heap, void *pt

static zend_always_inline void tracked_check_limit(zend_mm_heap *heap, size_t add_size) {
if (add_size > heap->limit - heap->size && !heap->overflow) {
#if ZEND_DEBUG
zend_mm_safe_error(heap,
"Allowed memory size of %zu bytes exhausted at %s:%d (tried to allocate %zu bytes)",
heap->limit, "file", 0, add_size);
#else
zend_mm_safe_error(heap,
"Allowed memory size of %zu bytes exhausted (tried to allocate %zu bytes)",
heap->limit, add_size);
#endif
zend_mm_safe_error(
heap,
"Allowed memory size of %zu bytes exhausted by %zu bytes"
# if ZEND_DEBUG
" at %s:%d"
# endif
". Allocated %zu bytes and need to allocate %zu bytes",

heap->limit, (add_size - (heap->limit - heap->real_size)),
# if ZEND_DEBUG
"file", 0,
# endif
heap->real_size, add_size
);
}
}

Expand Down
2 changes: 1 addition & 1 deletion ext/oci8/tests/pecl_bug10194.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,4 @@ require __DIR__.'/drop_table.inc';
echo "Done\n";
?>
--EXPECTF--
Fatal error: Allowed memory size of 10485760 bytes exhausted%s(tried to allocate %d bytes) in %s on line %d
Fatal error: Allowed memory size of %d bytes exhausted by %d bytes%S. Allocated %d bytes and need to allocate %d bytes in %s on line %d
2 changes: 1 addition & 1 deletion ext/oci8/tests/pecl_bug10194_blob.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,4 @@ echo "Done\n";
--EXPECTF--
Before load()

Fatal error: Allowed memory size of %d bytes exhausted%s(tried to allocate %d bytes) in %s on line %d
Fatal error: Allowed memory size of %d bytes exhausted by %d bytes%S. Allocated %d bytes and need to allocate %d bytes in %s on line %d
2 changes: 1 addition & 1 deletion ext/oci8/tests/pecl_bug10194_blob_64.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,4 @@ echo "Done\n";
--EXPECTF--
Before load()

Fatal error: Allowed memory size of %d bytes exhausted%s(tried to allocate %d bytes) in %s on line %d
Fatal error: Allowed memory size of %d bytes exhausted by %d bytes%S. Allocated %d bytes and need to allocate %d bytes in %s on line %d
2 changes: 1 addition & 1 deletion ext/standard/tests/streams/bug61115-1.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@ stream_context_get_options($fileResourceTemp);
ftruncate($fileResourceTemp, PHP_INT_MAX);
?>
--EXPECTF--
Fatal error: Allowed memory size of %d bytes exhausted%s(tried to allocate %d bytes) in %s on line %d
Fatal error: Allowed memory size of %d bytes exhausted by %d bytes%S. Allocated %d bytes and need to allocate %d bytes in %s on line %d
2 changes: 1 addition & 1 deletion ext/standard/tests/strings/chunk_split_variation3.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,4 @@ var_dump(chunk_split($body, $chunk_length));
Body generation
Using chunk_split()

Fatal error: Allowed memory size of %d bytes exhausted%s(tried to allocate %d bytes) in %s on line %d
Fatal error: Allowed memory size of %d bytes exhausted by %d bytes%S. Allocated %d bytes and need to allocate %d bytes in %s on line %d
2 changes: 1 addition & 1 deletion ext/standard/tests/strings/str_pad_variation1.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,4 @@ var_dump( str_pad($input, $php_int_max_pad_length) );
*** Testing str_pad() function: with large value for for 'pad_length' argument ***
str_pad(): Argument #2 ($length) must be of type int, float given

Fatal error: Allowed memory size of %d bytes exhausted%s(tried to allocate %d bytes) in %s on line %d
Fatal error: Allowed memory size of %d bytes exhausted by %d bytes%S. Allocated %d bytes and need to allocate %d bytes in %s on line %d
2 changes: 1 addition & 1 deletion ext/standard/tests/strings/wordwrap_memory_limit.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@ wordwrap($str, 1, $str2);

?>
--EXPECTF--
Fatal error: Allowed memory size of 134217728 bytes exhausted%s(tried to allocate %d bytes) in %s on line %d
Fatal error: Allowed memory size of %d bytes exhausted by %d bytes%S. Allocated %d bytes and need to allocate %d bytes in %s on line %d
2 changes: 1 addition & 1 deletion ext/zend_test/tests/observer_error_01.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ echo 'You should not see this.';
<!-- init str_repeat() -->
<str_repeat>

Fatal error: Allowed memory size of 2097152 bytes exhausted%s(tried to allocate %d bytes) in %s on line %d
Fatal error: Allowed memory size of %d bytes exhausted by %d bytes%S. Allocated %d bytes and need to allocate %d bytes in %s on line %d
</str_repeat:NULL>
</foo:NULL>
</file '%s%eobserver_error_%d.php'>