Bug #63206 [Com]: restore_error_handler does not restore previous errors mask

From: Date: Mon, 24 Feb 2020 21:26:15 +0000
Subject: Bug #63206 [Com]: restore_error_handler does not restore previous errors mask
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-225714@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=63206&edit=1 ID: 63206 Comment by: not-implemented at mark-plomer dot de Reported by: gwarnants at gmail dot com Summary: restore_error_handler does not restore previous errors mask Status: Open Type: Bug Package: *General Issues Operating System: Windows XP PHP Version: 5.4.7 Block user comment: N Private report: N New Comment: I created a draft-pull-request for this issue: https://github.com/php/php-src/pull/5206 @nikic: Independently from your proposal to not remove the error-handler while error-handling (which also makes sense), I think we always have to push the "empty" handler to the stack to have a consistent behaviour. This would fix this issue, but I'm not fully aware of the consequences. What do you think? Previous Comments: ------------------------------------------------------------------------ [2020-02-24 18:15:34] not-implemented at mark-plomer dot de The problem is not only about the "error mask". It affects the error-handler itself. Calling set/restore_error_handler() inside the error-handler "corrupts" the "old-error-handler" stack, when there are already >= 2 registered handlers. For future errors, the wrong error-handler is called. I run into this problem while debugging this issue in Sentry: https://github.com/getsentry/sentry-php/issues/976 Problem still exists in 7.4.3 (and probably "master"). Simpler test-script which also shows the use-case: Test script: ------------ set_error_handler(function() { echo 'First handler' . PHP_EOL; }); set_error_handler(function() { echo 'Second handler' . PHP_EOL; set_error_handler(function() { echo 'Internal handler' . PHP_EOL; }); $triggerInternalNotice++; // warnings while handling the error should go into internal handler restore_error_handler(); }); $triggerNotice1++; $triggerNotice2++; Expected result: ---------------- Second handler Internal handler Second handler Internal handler Actual result: -------------- Second handler Internal handler First handler ------------------------------------------------------------------------ [2017-12-28 18:07:19] nikic@php.net Generally restore_error_handler() does restore the mask as well. What happens here is that while the error handler is called, the error handler is temporarily removed to prevent recursion. The inner set_error_handler() call then thinks that there is no error handler registered and does not save the mask. Ideally we would not temporarily remove the error handler and instead track that it is currently running in a different way. ------------------------------------------------------------------------ [2016-06-03 14:31:34] a at ustimen dot co Sorry, my bad -- test script was not robust. Currently it repeats at PHP from 5.2 to nightly (7.x). Only under hhvm not repeats. https://travis-ci.org/garex/php-error-handler-bug/builds/135038478 ------------------------------------------------------------------------ [2016-06-03 14:06:57] a at ustimen dot co Currently repeats at 5.4, 5.5 and 5.6 Seems fixed in 7.0, hhvm and nightly. https://travis-ci.org/garex/php-error-handler-bug ------------------------------------------------------------------------ [2016-01-14 02:38:31] hujuice at inserviblie dot org Same here for PHP 5.6.14 on Linux ------------------------------------------------------------------------ The remainder of the comments for this report are too long. To view the rest of the comments, please view the bug report online at https://bugs.php.net/bug.php?id=63206 -- Edit this bug report at https://bugs.php.net/bug.php?id=63206&edit=1

« previous php.bugs (#225714) next »