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

Base sets Printexc.record_backtrace by default #77

Open
jberdine opened this issue Jun 30, 2019 · 3 comments
Open

Base sets Printexc.record_backtrace by default #77

jberdine opened this issue Jun 30, 2019 · 3 comments
Labels
forwarded-to-js-devs This report has been forwarded to Jane Street's internal review system.

Comments

@jberdine
Copy link

The module initialization code of base calls Backtrace.initialize_module, which (unless OCAMLRUNPARAM is set) calls Printexc.record_backtrace true.

This is a significant performance foot-gun, and as far as I can see, not documented anywhere outside the code.

Aside: It's not clear to me that libraries have any business setting global state like this, but presumably there was an argument for this being the right default.

@yminsky
Copy link
Contributor

yminsky commented Jul 1, 2019

Seems like a reasonable point. I feel pretty strongly that recording backtraces is the right default, but I agree it is odd to have this enforced at the library level, and surprising for users of Base.

FWIW, I believe it's only a performance issue when you're using exceptions a lot, which I think would mostly arise when you're using exceptions for fine-grained control flow. This is not a good pattern most of the time, and when you do need it, you can use Exn.raise_without_backtrace

@jberdine
Copy link
Author

jberdine commented Jul 1, 2019

Yes, this is only going to hurt when exceptions are used a lot, and especially when they are raised from deeply-recursive functions.

I'm not sure that control-flow versus handlable-crash is an easy distinction to make for libraries though. For instance, Map.find_exn could go either way depending on usage (either a missing key is used to represent the map sparsely, or it's a failure mode, the library can't know). Probably a good eventual situation is for libraries to use raise_notrace for their internal control flow, and expose external interfaces so that exceptions cross the boundary only in failure situations. But at the moment there is a lot of code that predates raise_notrace.

Also note that since 4.04, the overhead of recording backtraces seems to apply even on code compiled without -g: ocaml/ocaml#8780.

@yminsky
Copy link
Contributor

yminsky commented Jul 2, 2019

This doesn't line up with my experience. Code that uses exceptions for control flow typically is doing so explicitly, rather than relying on exceptions thrown by Map.find_exn. There are tradeoffs, but I think a pretty good compromise is having slower-but-more-informative exceptions by default, with the ability to raise uninformative exceptions when needed.

That said, having this choice forced upon you by Base isn't great.

@github-iron github-iron added the forwarded-to-js-devs This report has been forwarded to Jane Street's internal review system. label Sep 16, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
forwarded-to-js-devs This report has been forwarded to Jane Street's internal review system.
Projects
None yet
Development

No branches or pull requests

3 participants