Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix crash during GC of suspended generator delegate #15275

Merged
merged 3 commits into from
Aug 10, 2024

Conversation

arnaud-lb
Copy link
Member

We assume that non-running generators have their ->execute_data->opline pointing to the opline next to the yield or yield from that stopped it (e.g. here, here, and here).

However, when fetching the next delegated value for a yield from $nonGenerator, the opline points to the yield from op due to temporary adjustments in zend_generator_get_next_delegated_value().

This causes crashes when cleaning up unfinished calls or assertion failures during GC.

Here I change zend_generator_get_next_delegated_value() to not adjust the opline, so that the expectation is always true.

zend_generator_throw_exception() also adjusts the opline, which causes similar issues if zval_ptr_dtor(&generator->values) triggers the GC. I update it to cancel the adjustment before destroying generator->values.

Alternatively, I think it may be simpler to stop incrementing opline in the yield and yield from op handlers (and to leave this task to zend_generator_resume()), so that we don't have to patch opline in other places. However this targets 8.2, so I didn't explore this idea.

While testing I've also found that calling ->throw() on a running generator, or a child of a running generator, may crash. In [1], the getIterator() generator is getting closed during ->throw(), but its execute_data is accessed after that. In [2] we break zend_generator_throw_exception()'s assumption of being called on a non-running generator. Should we forbid calling ->throw() when zend_generator_get_current() is running?

@arnaud-lb arnaud-lb requested a review from bwoebi August 7, 2024 14:31
@arnaud-lb arnaud-lb marked this pull request as ready for review August 7, 2024 15:05
@iluuu1994 iluuu1994 removed their request for review August 7, 2024 16:50
Copy link
Member

@dstogov dstogov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is your code.
You know it better then me.
I don't object.

@bwoebi
Copy link
Member

bwoebi commented Aug 7, 2024

This is sort-of annoying, as the opline now won't point to the line with the yield (from) in stack traces in zend_generator_throw_exception thrown by generator->values destructors (if I understood it correctly?).

I think it would be actually beneficial to not replace the line numbers by %d in these tests.

@arnaud-lb
Copy link
Member Author

This is sort-of annoying, as the opline now won't point to the line with the yield (from) in stack traces in zend_generator_throw_exception thrown by generator->values destructors (if I understood it correctly?).

I think the line number will be correct, luckily, most of the time: YIELD_FROM is probably always followed by an op with the same line number (FREE, ASSIGN, SEND, or other uses of its result).

I think it would be actually beneficial to not replace the line numbers by %d in these tests.

Agreed, I've updated the tests

Copy link
Member

@bwoebi bwoebi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose it's fine then. But yeah, I very much prefer the other patch, which can land only in master though, so please replace it by that one when merging to master.

@arnaud-lb arnaud-lb merged commit c767fec into php:PHP-8.2 Aug 10, 2024
8 checks passed
arnaud-lb added a commit to arnaud-lb/php-src that referenced this pull request Aug 10, 2024
arnaud-lb added a commit to arnaud-lb/php-src that referenced this pull request Aug 10, 2024
* PHP-8.2:
  [ci skip] NEWS for phpGH-15275
  Fix crash during GC of suspended generator delegate (php#15275)
arnaud-lb added a commit to arnaud-lb/php-src that referenced this pull request Aug 10, 2024
arnaud-lb added a commit to arnaud-lb/php-src that referenced this pull request Aug 10, 2024
* PHP-8.3:
  [ci skip] NEWS for phpGH-15275
  [ci skip] NEWS for phpGH-15275
  Fix crash during GC of suspended generator delegate (php#15275)
arnaud-lb added a commit to arnaud-lb/php-src that referenced this pull request Aug 10, 2024
arnaud-lb added a commit that referenced this pull request Aug 10, 2024
* PHP-8.3:
  [ci skip] NEWS for GH-15275
  [ci skip] NEWS for GH-15275
  Fix crash during GC of suspended generator delegate (#15275)
arnaud-lb added a commit that referenced this pull request Aug 10, 2024
arnaud-lb added a commit that referenced this pull request Aug 10, 2024
YIELD and YIELD_FROM increment opline before returning, but in most places
we need the opline to point to the YIELD and YIELD_FROM.

Here I change YIELD / YIELD_FROM to not increment opline. This simplifies the
code and fixes GH-15275 in a better way.

Closes GH-15328
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants