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

From: Date: Mon, 24 Feb 2020 18:15:34 +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-225713@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:

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


Previous Comments:
------------------------------------------------------------------------
[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

------------------------------------------------------------------------
[2013-10-06 06:55:51] gwarnants at gmail dot com

Same problem in 5.3.4 on Windows

------------------------------------------------------------------------


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


Thread (12 messages)

« previous php.bugs (#225713) next »