php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #77575 set_error_handler() / ErrorException memory leak
Submitted: 2019-02-06 02:55 UTC Modified: 2019-08-28 11:27 UTC
Votes:1
Avg. Score:3.0 ± 0.0
Reproduced:0 of 0 (0.0%)
From: frame86 at live dot com Assigned:
Status: Not a bug Package: *General Issues
PHP Version: 7.2.14 OS: Ubuntu 18.04.1 LTS
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: frame86 at live dot com
New email:
PHP Version: OS:

 

 [2019-02-06 02:55 UTC] frame86 at live dot com
Description:
------------
Using an error handler, throwing and catching the ErrorException leaks memory.

Test script:
---------------
<?php

$last = time();
ini_set('memory_limit', '8G');

set_error_handler(function ($severity, $message, $file, $line) {
	throw new \ErrorException($message, 0, $severity, $file, $line);
});

while(true)
{
	try {
		trigger_error("Something");
	} catch(\Throwable $e) {
		
	}
	
	if(time() - $last >= 1) {
		$last = time();
		printf("\nMemory: %.4f", memory_get_usage() / (1024 * 1024));
	}

        gc_collect_cycles(); // doesn't help much
}

Expected result:
----------------
Nearly constant memory usage

Actual result:
--------------
Memory: 3.7187
Memory: 5.0504
Memory: 6.0593
Memory: 6.9050
Memory: 7.6437
Memory: 8.3095
Memory: 8.9218
Memory: 9.4904
...
Memory: 97.7963
Memory: 219.5202
Memory: 300.1706
Segmentation fault (core dumped)


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2019-08-28 11:27 UTC] nikic@php.net
-Status: Open +Status: Not a bug
 [2019-08-28 11:27 UTC] nikic@php.net
The reason is that the error handler receives the variable scope (including $e) and the exception includes the backtrace including arguments, which also includes that variable scope. So effectively you're constructing a very long and bulky linked list of exceptions.

What you can do:
 * On any version: unset($e)
 * On PHP 7.4: Set zend.exception_ignore_args=1 to disable arg collection
 * On PHP 8.0: Variable scope is no longer passed to error handler, so the issue doesn't exist.
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Sat Jul 05 04:01:35 2025 UTC