Skip to content

Commit 2612448

Browse files
committed
Add observer support for fatal errors
1 parent 322798f commit 2612448

File tree

4 files changed

+106
-0
lines changed

4 files changed

+106
-0
lines changed

Zend/zend.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1323,6 +1323,16 @@ static ZEND_COLD void zend_error_impl(
13231323

13241324
zend_observer_error_notify(type, error_filename, error_lineno, message);
13251325

1326+
/* Call all the observer end handlers for fatal errors */
1327+
if (ZEND_OBSERVER_ENABLED && (type & E_FATAL_ERRORS) && EG(current_execute_data)) {
1328+
zend_execute_data *ex = EG(current_execute_data);
1329+
do {
1330+
if (ex->func->type != ZEND_INTERNAL_FUNCTION) {
1331+
zend_observer_fcall_end(ex, NULL);
1332+
}
1333+
} while ((ex = ex->prev_execute_data) != NULL);
1334+
}
1335+
13261336
/* if we don't have a user defined error handler */
13271337
if (Z_TYPE(EG(user_error_handler)) == IS_UNDEF
13281338
|| !(EG(user_error_handler_error_reporting) & type)
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
--TEST--
2+
Observer: End handlers fire after a fatal error
3+
--SKIPIF--
4+
<?php if (!extension_loaded('zend-test')) die('skip: zend-test extension required'); ?>
5+
--INI--
6+
zend_test.observer.enabled=1
7+
zend_test.observer.observe_all=1
8+
zend_test.observer.show_return_value=1
9+
memory_limit=1M
10+
--FILE--
11+
<?php
12+
function foo()
13+
{
14+
str_repeat('.', 1024 * 1024 * 2); // 2MB
15+
}
16+
17+
foo();
18+
19+
echo 'You should not see this.';
20+
?>
21+
--EXPECTF--
22+
<!-- init '%s/observer_error_%d.php' -->
23+
<file '%s/observer_error_%d.php'>
24+
<!-- init foo() -->
25+
<foo>
26+
</foo:NULL>
27+
</file '%s/observer_error_%d.php'>
28+
29+
Fatal error: Allowed memory size of 2097152 bytes exhausted%s(tried to allocate %d bytes) in %s on line %d
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
--TEST--
2+
Observer: End handlers fire after a userland fatal error
3+
--SKIPIF--
4+
<?php if (!extension_loaded('zend-test')) die('skip: zend-test extension required'); ?>
5+
--INI--
6+
zend_test.observer.enabled=1
7+
zend_test.observer.observe_all=1
8+
zend_test.observer.show_return_value=1
9+
--FILE--
10+
<?php
11+
function foo()
12+
{
13+
trigger_error('Foo error', E_USER_ERROR);
14+
}
15+
16+
foo();
17+
18+
echo 'You should not see this.';
19+
?>
20+
--EXPECTF--
21+
<!-- init '%s/observer_error_%d.php' -->
22+
<file '%s/observer_error_%d.php'>
23+
<!-- init foo() -->
24+
<foo>
25+
</foo:NULL>
26+
</file '%s/observer_error_%d.php'>
27+
28+
Fatal error: Foo error in %s on line %d
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
--TEST--
2+
Observer: non-fatal errors do not fire end handlers prematurely
3+
--SKIPIF--
4+
<?php if (!extension_loaded('zend-test')) die('skip: zend-test extension required'); ?>
5+
--INI--
6+
zend_test.observer.enabled=1
7+
zend_test.observer.observe_all=1
8+
zend_test.observer.show_return_value=1
9+
--FILE--
10+
<?php
11+
function foo()
12+
{
13+
return $this_does_not_exit; // E_WARNING
14+
}
15+
16+
function main()
17+
{
18+
foo();
19+
echo 'After error.' . PHP_EOL;
20+
}
21+
22+
main();
23+
24+
echo 'Done.' . PHP_EOL;
25+
?>
26+
--EXPECTF--
27+
<!-- init '%s/observer_error_%d.php' -->
28+
<file '%s/observer_error_%d.php'>
29+
<!-- init main() -->
30+
<main>
31+
<!-- init foo() -->
32+
<foo>
33+
34+
Warning: Undefined variable $this_does_not_exit in %s on line %d
35+
</foo:NULL>
36+
After error.
37+
</main:NULL>
38+
Done.
39+
</file '%s/observer_error_%d.php'>

0 commit comments

Comments
 (0)