From 02d7641af9cd47739e0e27986357d13945b65491 Mon Sep 17 00:00:00 2001 From: Daniil Gentili Date: Wed, 9 Jul 2025 13:56:39 +0200 Subject: [PATCH 1/5] Invoke destructors after fatal error to match shutdown handlers --- main/main.c | 1 - 1 file changed, 1 deletion(-) diff --git a/main/main.c b/main/main.c index 3518e4137ecef..c452015545a3f 100644 --- a/main/main.c +++ b/main/main.c @@ -1474,7 +1474,6 @@ static ZEND_COLD void php_error_cb(int orig_type, zend_string *error_filename, c if (!(orig_type & E_DONT_BAIL)) { /* restore memory limit */ zend_set_memory_limit(PG(memory_limit)); - zend_objects_store_mark_destructed(&EG(objects_store)); if (CG(in_compilation) && (type == E_COMPILE_ERROR || type == E_PARSE)) { /* We bailout during compilation which may for example leave stale entries in CG(loop_var_stack). * If code is compiled during shutdown, we need to make sure the compiler is reset to a clean state, From 42fbfadefc0b97a8277d144c12133f08f3ab2144 Mon Sep 17 00:00:00 2001 From: Daniil Gentili Date: Wed, 9 Jul 2025 13:58:57 +0200 Subject: [PATCH 2/5] Bump UPGRADING --- UPGRADING | 2 ++ 1 file changed, 2 insertions(+) diff --git a/UPGRADING b/UPGRADING index 7b264b0703bc1..0cc0c88679c68 100644 --- a/UPGRADING +++ b/UPGRADING @@ -588,6 +588,8 @@ PHP 8.5 UPGRADE NOTES . The high resolution timer (`hrtime()`) on macOS now uses the recommended `clock_gettime_nsec_np(CLOCK_UPTIME_RAW)` API instead of `mach_absolute_time()`. + . Destructors are now invoked correctly after bailout, to match the behavior + of shutdown handlers. - CLI/CGI: . The `-z` or `--zend-extension` option has been removed as it was From 14c9a5a5ab34b1ae8b502df9cff45eff6fdf74e5 Mon Sep 17 00:00:00 2001 From: Daniil Gentili Date: Wed, 9 Jul 2025 14:50:18 +0200 Subject: [PATCH 3/5] Fixup tests --- Zend/tests/fibers/fatal-error-with-multiple-fibers.phpt | 3 ++- ext/zend_test/tests/observer_fiber_functions_03.phpt | 9 +++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/Zend/tests/fibers/fatal-error-with-multiple-fibers.phpt b/Zend/tests/fibers/fatal-error-with-multiple-fibers.phpt index 875364c3f6b02..900d0bf5b8842 100644 --- a/Zend/tests/fibers/fatal-error-with-multiple-fibers.phpt +++ b/Zend/tests/fibers/fatal-error-with-multiple-fibers.phpt @@ -7,7 +7,7 @@ $fiber1 = new Fiber(function (): void { try { \Fiber::suspend(1); } finally { - echo "not executed"; + echo "executed"; } }); @@ -28,3 +28,4 @@ int(2) Deprecated: Passing E_USER_ERROR to trigger_error() is deprecated since 8.4, throw an exception or call exit with a string message instead in %s on line %d Fatal error: Fatal error in fiber in %sfatal-error-with-multiple-fibers.php on line %d +executed \ No newline at end of file diff --git a/ext/zend_test/tests/observer_fiber_functions_03.phpt b/ext/zend_test/tests/observer_fiber_functions_03.phpt index 8e267ea65a037..e5ddade241216 100644 --- a/ext/zend_test/tests/observer_fiber_functions_03.phpt +++ b/ext/zend_test/tests/observer_fiber_functions_03.phpt @@ -87,3 +87,12 @@ Fatal error: Allowed memory size of 104857600 bytes exhausted %s on line %d + + + + + + + + + \ No newline at end of file From 34ce321c70ddbc00a036fe569573da5b7d015541 Mon Sep 17 00:00:00 2001 From: Daniil Gentili Date: Wed, 9 Jul 2025 14:52:38 +0200 Subject: [PATCH 4/5] Add test --- .../invoke_destructors_after_bailout.phpt | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 Zend/tests/invoke_destructors_after_bailout.phpt diff --git a/Zend/tests/invoke_destructors_after_bailout.phpt b/Zend/tests/invoke_destructors_after_bailout.phpt new file mode 100644 index 0000000000000..3ede89d7928a8 --- /dev/null +++ b/Zend/tests/invoke_destructors_after_bailout.phpt @@ -0,0 +1,41 @@ +--TEST-- +Invoke destructors after bailout +--SKIPIF-- + +--FILE-- +stats)."\n"; + exit(0); + } + + public function inc(string $key, int $by = 1): void { + $this->stats[$key] ??= 0; + $this->stats[$key] += $by; + } +} + +StatCounter::get()->inc('test'); +StatCounter::get()->inc('test2'); + +set_time_limit(1); +while (1); + +?> +--EXPECTF-- + +Fatal error: Maximum execution time of 1 second exceeded in %s on line %d +Sending stats: {"test":1,"test2":1} From b945b5e8f6dd731496d672a6204dcf3636cac922 Mon Sep 17 00:00:00 2001 From: Daniil Gentili Date: Wed, 9 Jul 2025 14:57:48 +0200 Subject: [PATCH 5/5] Cleanup --- Zend/tests/invoke_destructors_after_bailout.phpt | 1 - 1 file changed, 1 deletion(-) diff --git a/Zend/tests/invoke_destructors_after_bailout.phpt b/Zend/tests/invoke_destructors_after_bailout.phpt index 3ede89d7928a8..344eb891c1799 100644 --- a/Zend/tests/invoke_destructors_after_bailout.phpt +++ b/Zend/tests/invoke_destructors_after_bailout.phpt @@ -19,7 +19,6 @@ final class StatCounter { public function __destruct() { echo "Sending stats: ".json_encode($this->stats)."\n"; - exit(0); } public function inc(string $key, int $by = 1): void {