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

Catch exceptions in main()? #664

Closed
elfring opened this issue Apr 14, 2013 · 15 comments
Closed

Catch exceptions in main()? #664

elfring opened this issue Apr 14, 2013 · 15 comments

Comments

@elfring
Copy link

elfring commented Apr 14, 2013

I expect that exception handling is usually supported by a C++ program. I wonder why your function "main" does not contain corresponding try and catch instructions so far.

How do you think about recommendations by Matthew Wilson in an article?

Would you like to adjust the implementation if you consider effects for uncaught/unhandled exceptions like they are described by Danny Kalev?

@KamilaBorowska
Copy link
Contributor

Codebase of this project doesn't use throw at all, and I don't think it needs it. The original codebase was written in C, and costs of implementing throw everywhere aren't worth it - it would have to be added everywhere, yet in many cases, the only thing we could do is quiting. Currently, fatal errors show error message, stacktrace and quit - but that's debug() function, not throw.

catch without throw is useless, so I think that this issue won't be accepted.

@elfring
Copy link
Author

elfring commented Apr 14, 2013

How do you think about to adjust your main() functions to cope with exceptions like "std::bad_alloc" gracefully?

Would you like to become independent from the technical detail that it is implementation-defined if stack unwinding will be performed by the compiler run time software after uncaught C++ exceptions are processed?

@ridiculousfish
Copy link
Member

exceptions in fish are only used for programming errors, or unrecoverable error conditions. That includes bad_alloc, out_of_range, and others.

If exceptions are left unhandled, then throw will call abort, and we can get a backtrace (see for example #511). But If we add an outermost exception handling block, to my knowledge, we lose the backtrace information from where the exception is thrown.

Also, the savings from building with -fno-exceptions are substantial. A quick test shows that enabling exception support increases fish's compiled size by 25% (from 601 KB to 754 KB).

For these reasons I think we should not catch exceptions, and furthermore disable exception support whenever the standard library permits it.

@elfring
Copy link
Author

elfring commented Apr 15, 2013

Where do you pass the parameter "no-exceptions"?

Do you care if destructors will ever be called also in exceptional situations?

@JanKanis
Copy link
Contributor

Fish unconditionally terminates when an exception happens, and it also
shows a stacktrace in such cases. So its behavior is already exactly as the
article by Matthew Wilson suggests, fish has the same behavior as python
and ruby. Fish doesn't use (afaik) any complicated destructors, so not
freeing memory or closing file descriptors when exceptions happen fine.

On 14 April 2013 18:15, Markus Elfring notifications@github.com wrote:

I expect that exception handling is usually supported by a C++ program. I
wonder why your function "mainhttps://github.com/fish-shell/fish-shell/blob/73046ec838ca90cbf7e1ea1b1ac89f5c44eec52d/fish.cpp#L416"
does not contain corresponding try and catch instructionshttp://stackoverflow.com/questions/368184/does-it-make-sense-to-catch-exceptions-in-the-mainso far.

How do you think about recommendations by Matthew Wilson in an articlehttp://accu.org/index.php/journals/1706
?

Would you like to adjust the implementation if you consider effects for
uncaught/unhandled exceptionshttp://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=108like they are described by Danny Kalev?


Reply to this email directly or view it on GitHubhttps://github.com//issues/664
.

@elfring
Copy link
Author

elfring commented Apr 15, 2013

I find that Matthew presents a different view for "a production-quality main()".
Your description is clear for the current fish tool implementation.

@KamilaBorowska
Copy link
Contributor

This looks like programming for unlikely. Of course if somebody will delete half of the files on the system, the fish isn't expected to start (unless you're lucky). If the system has 2MB of RAM, you shouldn't expect fish to start. If your system thinks that /usr is actually /tmp, don't expect things to be sane. If your system randomly decided to return incorrect values in standard functions, don't expect fish to work. If the RAM is broken, expect fish to randomly freeze. If you don't have python, don't expect fish to work 100% perfectly. If your system doesn't have hostname binary, expect lots of errors. If you have evil process that randomly sends SIGSEGV to processes, fish will return exception. If you have Windows, don't expect it to work.

The problem is, where to set the boundary. Do you really think we should have check entire RAM before starting, checking whatever every binary does what it should, system calls don't randomly fail because person who wrote OS is evil, and find the processes can randomly can send SIGSEGV to fish?

Bugfree software isn't possible. This is example of contrived bug. Of course if the fish doesn't have enough memory. But it does fail gracefully... by crashing with message "Out of memory" and backtrace. Just like in this example. Fish wasn't coded to detect lack of space left on device, yet it makes an error - and doesn't actually crash (because this isn't fatal error, fish still works, even if it cannot write to stdout).

glitchmr@pineapple ~> fish -c'echo Hello, world!' > /dev/full
Error while writing to stdout
write_loop: No space left on device
fish: Backtrace:
fish(_Z15show_stackframev+0x4d) [0x49df5d]
fish(_Z4execR8parser_tP5job_t+0x1f90) [0x451620]
fish(_ZN8parser_t8eval_jobEP11tokenizer_t+0x3de) [0x472dee]
fish(_ZN8parser_t4evalERKSbIwSt11char_traitsIwESaIwEERK10io_chain_t12block_type_t+0x83c) [0x473aac]
fish(main+0x5f8) [0x4203f8]
/usr/lib/libc.so.6(__libc_start_main+0xf5) [0x7fd07f8d5a15]
fish() [0x420d19]
glitchmr@pineapple ~>

I would make example of out-of-memory error, but I have lots of RAM, and I doubt I could cause that without causing lots of other issues in other programs that weren't prepared for that - I wouldn't want to restart my computer because random service crashed because out of memory. You cannot do much anyway, when you don't have memory - you can only fail.

glitchmr@pineapple ~> perl -E 'my $a = "a" x 1_000_000_000_000_000'
Out of memory!

@ridiculousfish
Copy link
Member

@elfring:

We currently don't pass -fno-exceptions for the autotools build - we ought to though. I should make that change.

Destructors should never be called at exit in fish, because all they do is make exit slower. Necessary cleanups are handled in main(). We have a function exit_without_destructors, which I see main does not call - it ought to. I should make that change too!

@elfring
Copy link
Author

elfring commented Apr 16, 2013

How do you think about the possibility to let any users choose which error handling strategy should be applied for their tool implementation?

@KamilaBorowska
Copy link
Contributor

Nope. fish will never have configuration option to change whatever to call destructors or not on exit. Or for how errors will be reported. fish doesn't want to copy zsh with its minor options that nobody cares about.  Besides, that one would only contribute to configuration hell. Many things actually aren't configurable in fish, and I like that about fish.

Besides, nobody cares whatever destructors are called or not on exit. Destructors in fish only free memory, they aren't used for flow control or saving data on hard drive. If you have modern operating system (that is, more modern than Windows 98), the memory is automatically freed when the process is closed.

Markus Elfring notifications@github.com wrote:

How do you think about the possibilty to let any users decide which error handling strategy should be applied for their tool implementation?


Reply to this email directly or view it on GitHub.

@ridiculousfish
Copy link
Member

-fno-exceptions in the autotools build is f934310
exiting without destructors is e285d29

@elfring
Copy link
Author

elfring commented Apr 19, 2013

How do you think about to check if this special build parameter is supported by the used compiler?
Do other tools provide a similar configuration option (as "g++")?

@ridiculousfish
Copy link
Member

Yes, we only pass -fno-exceptions when compiling with g++ (or with clang in the Xcode build for OS X)

@elfring
Copy link
Author

elfring commented Apr 21, 2013

Would you like to achieve a consistent parameter specification for different compilers?

Do you care if open streams will be closed and functions which were registered with atexit() will be called?

@zanchey
Copy link
Member

zanchey commented Jul 30, 2015

I don't think there is going to be any change to the current behaviour here. fish doesn't have any atexit functions, nor does it have streams open that need flushing.

@zanchey zanchey closed this as completed Jul 30, 2015
@faho faho removed this from the fish-future milestone Feb 5, 2016
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Apr 18, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants