-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Fix GH-14361: Deep recursion in zend_cfg.c causes segfault instead of error #14432
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
Conversation
I think it's better to switch to iterative reachability mark algorithm (e.g. using zend_worklist) |
5579b4c
to
d2b79af
Compare
I agree. I changed it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. This looks almost fine.
Please make the final touch - remove the redundant tail-call optimization.
I don't care about passing zend_basic_block
or its index.
Maybe, it would be better to not pass it at all and push the start BB here.
Zend/Optimizer/zend_cfg.c
Outdated
if (i == b->successors_count - 1) { | ||
/* Tail call optimization */ | ||
if (succ->flags & ZEND_BB_REACHABLE) { | ||
return; | ||
finished = true; | ||
break; | ||
} | ||
|
||
b = succ; | ||
break; | ||
} else { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Iterative algorithm doesn't need tail call optimization any more.
This code may be removed as well as while (!finished) {
loop.
Thanks, removed the tail call optimization
We currently don't always start from the entry block so I didn't change it here. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks fine.
Building the CFG for JIT or optimizations can run into deep recursion, and depending on the stack limit cause a segfault. This patch uses the stack limit check to fail out of those cases. This prevents a segfault.
We use this check elsewhere in the compiler as well. However, in this case we just make optimizations or JIT fail without aborting the application such that code can still execute.
The attached test case will succeed both without and with this patch, it is mainly intended to test if propagating failure doesn't cause crashes. To reproduce the issue, set a low stack limit using
ulimit -s
and run the original test case from #14361