Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[Console] Fix exit status on uncaught exception with negative code #45851

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

Merged
merged 1 commit into from
Mar 27, 2022

Conversation

acoulton
Copy link
Contributor

Q A
Branch? 4.4
Bug fix? yes
New feature? no
Deprecations? no
Tickets Fix #45850
License MIT
Doc PR N/A

As described in #45850, if an application threw an exception with the code property set to a negative number this could in some cases cause the process to appear to exit 'successfully' with a zero exit status. Exiting with any negative number produces potentially unexpected results - the reported exit status will not appear to match the value that was set. This is due to the binary handling / truncation of exit codes.

This PR may theoretically break BC for applications that were intentionally throwing exceptions with negative codes and
performing some action based on that status.
However, given they would have had to implement an algorithm to map e.g. -10 in PHP to 246 as the actual exit status, it seems unlikely this is a common usage.

IMO therefore applications using negative statuses are relying on an undocumented / incorrect implementation, and this is not a formal BC break.

I believe it is essentially safe to assume that exceptions with negative codes are e.g. being thrown by lower-level components, and are not intended to set a shell exit status.

Coalescing all negative numbers to 1 matches the existing behaviour with other 'invalid' exception codes e.g. empty / zero / non-numeric.

This therefore feels the most robust fix and eliminates any potential for confusion.

@carsonbot
Copy link

It looks like you unchecked the "Allow edits from maintainer" box. That is fine, but please note that if you have multiple commits, you'll need to squash your commits into one before this can be merged. Or, you can check the "Allow edits from maintainers" box and the maintainer can squash for you.

Cheers!

Carsonbot

@acoulton
Copy link
Contributor Author

It looks like appveyor failed on a network issue - I'm not sure how to make that retry - and the coding standards report is for existing content in the testcase that is not modified here.

Copy link
Member

@fabpot fabpot left a comment

Choose a reason for hiding this comment

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

Small CS issue but it looks good to me.

@fabpot
Copy link
Member

fabpot commented Mar 26, 2022

As there is a potential behavior change (even if theoretical only), I would do the change on 6.1 instead and add a note in the CHANGELOG file to document the change.

@acoulton
Copy link
Contributor Author

@fabpot the only issue with targeting 6.1 is we're currently still tied to 4.4 due to third-party dependencies.

As it stands our CI occasionally false-positives when in fact the process has crashed. We've now had two branches (that we know of) where code has been merged with failing tests that have not shown up till a later run. And more times it has occurred during work on a branch. Essentially we can't trust our green tick now, and have to check the output of every build. There may well be other users who have cron/CI/etc processes that are failing undetected.

That feels like quite a significant bug. It is definitely higher impact than the possibility someone starts to see failures due to an unexpected but still nonzero exit code.

So it should really be fixed in the first supported version IMO.

If you're not happy to change all negative values in 4.4 then I think at least we should change anything < -255. Values lower than that are very clearly not valid exit codes, so changing them seems reasonable even in the older versions.

Then I could do a separate PR for 6.1 to apply this broader change to get rid of all negative values, which I think is best long-term.

What do you think?

@acoulton
Copy link
Contributor Author

PS thank you for the quick weekend review!

@fabpot
Copy link
Member

fabpot commented Mar 26, 2022

As you said, someone might rely on the current behavior. From my past experience, whenever we said that it was ok to merge something because there is 0 chance someone would have used the bad behavior, we had to revert because someone somewhere did rely on the behavior.

So, we have decided quite a while ago to not play this game anymore and always only merge bug fixes.

I know that this is frustrating, but we want to be on the safe side and try to minimize BC breaks as much as possible.

I hope you will understand our position.

@acoulton
Copy link
Contributor Author

@fabpot ok fair enough for the general negative number case.

But surely nobody can be relying on throw new Exception ('not really', -256) (or -512 etc), allowing that to bubble out of their app and expecting that to terminate the app with an exit code of zero?

That is 100% a bug IMO - and a nasty one - and I can't see any valid reason not to fix it.

If you wanted to limit the behaviour change to the bare minimum then I suppose the fix could only change the specific -256,-512,... values that result in a zero. But that is very inconsistent with how you handle positive numbers >= 256.

@fabpot
Copy link
Member

fabpot commented Mar 26, 2022

I must admit that you have a point here :)

Can you fix the CS issue so that I can merge it in 4.4.

@acoulton
Copy link
Contributor Author

@fabpot thanks very much. Of course, I'll sort that when I'm back at my machine later on.

@kaznovac
Copy link
Contributor

Negative error codes have unspecified (implementation/environment specific - in most cases it's modulo 256) behavior, only codes 0-255 are defined.

https://tldp.org/LDP/abs/html/exitcodes.html

So this is rather a bug fix rather than a BC.

As described in symfony#45850, if an application threw an exception with
the `code` property set to a negative number this could in some
cases cause the process to appear to exit 'successfully' with a
zero exit status.

Exiting with any negative number produces potentially unexpected
results - the reported exit status will not appear to match the
value that was set. This is due to the binary handling /
truncation of exit codes.

This may theoretically break BC for applications that were
intentionally throwing exceptions with negative codes and
performing some action based on that status. However, given they
would have had to implement an algorithm to map e.g. `-10` in
PHP to `246` as the actual exit status, it seems unlikely this
is a common usage. It is certainly outside the defined behaviour
of POSIX exit codes.

Therefore I believe it is essentially safe to assume that exceptions
with negative codes are e.g. being thrown by lower-level components,
and are not intended to set a shell exit status.

Coalescing all negative numbers to 1 matches the existing behaviour
with other 'invalid' exception codes e.g. empty / zero / non-numeric.

This therefore feels the most robust fix and eliminates any potential
for confusion.

Fixes symfony#45850
@acoulton acoulton force-pushed the TICKET_45850_negative_exit_status branch from b152cbb to e7072aa Compare March 26, 2022 22:14
@acoulton acoulton requested a review from fabpot March 26, 2022 22:35
@acoulton
Copy link
Contributor Author

@fabpot thanks for spotting the CS issue I've corrected that now.

@fabpot
Copy link
Member

fabpot commented Mar 27, 2022

Thank you @acoulton.

@fabpot fabpot merged commit 7b43f0f into symfony:4.4 Mar 27, 2022
@acoulton acoulton deleted the TICKET_45850_negative_exit_status branch March 28, 2022 10:51
@acoulton
Copy link
Contributor Author

Thanks very much @fabpot

This was referenced Apr 2, 2022
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.

4 participants