You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I think the issue is that zend_test_create_throwing_resource() will install the exception on the test() frame, unwind to main(), throw for the freed $resource variable, and verify that the exception op is set (which it isn't, as it was set in test() and only rethrown later.
Two possible solutions are:
Switch to the previous stack frame after freeing the stack frames variables. This has some observable effects, namely for destructors. This might or might not matter.
Adjust opline of the restored stack frame earlier. This seems like the less risky solution.
Looking a bit closer into this, ZEND_DO_ICALL is also susceptible to the same issue. It also restores the previous call frame and then freeing the popped stack frames variables without rethrowing first. I can't reproduce the issue though because the exception keeps the passed reference alive.
@nielsdos I think it's ok to just remove these asserts. We don't have a good way to check whether we just switched to this frame and the exception opline will be installed later. Do you want to send a PR, since this was your original idea?
Activity
ndossche commentedon Jan 9, 2025
Simplified test:
ndossche commentedon Jan 9, 2025
The assertion may be too conservative, as the HANDLE_EXCEPTION is set later on. But I'm not sure (yet).
iluuu1994 commentedon Jan 16, 2025
This can be reproduced a bit simpler:
I think the issue is that
zend_test_create_throwing_resource()will install the exception on thetest()frame, unwind tomain(), throw for the freed$resourcevariable, and verify that the exception op is set (which it isn't, as it was set intest()and only rethrown later.Two possible solutions are:
Details
WDYT?
iluuu1994 commentedon Jan 16, 2025
Looking a bit closer into this,
ZEND_DO_ICALLis also susceptible to the same issue. It also restores the previous call frame and then freeing the popped stack frames variables without rethrowing first. I can't reproduce the issue though because the exception keeps the passed reference alive.Maybe it's better to adjust the assertion, rather than adding additional checks everywhere.
ndossche commentedon Jan 17, 2025
I think the assertion should be adjusted because the end result works anyway
iluuu1994 commentedon Jan 18, 2025
Yeah I think I agree.
iluuu1994 commentedon Jan 20, 2025
@nielsdos I think it's ok to just remove these asserts. We don't have a good way to check whether we just switched to this frame and the exception opline will be installed later. Do you want to send a PR, since this was your original idea?
ndossche commentedon Jan 20, 2025
@iluuu1994 Well you did the more in-depth analysis, so it's at least a joint effort. I'll make a PR and add your C-o-b tag
Fix GH-17408: Assertion failure Zend/zend_exceptions.c
Merge branch 'PHP-8.3' into PHP-8.4
Merge branch 'PHP-8.4'