-
Notifications
You must be signed in to change notification settings - Fork 83
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
canonical abi should have a way to terminate the program #47
Comments
Yes, something in this space makes sense. I'm assuming we want "termination" to not have the "something bad happened" connotation of trapping so that modules could use it regularly without hosts presenting the executions as errors to the developer. From a composability point of view (in which there are multiple components linked together, and one does a terminate), there are a few interesting options. E.g.: if component A calls component B and B "terminates":
The least drastic option seems like 1a (which would almost correspond to wasm exception handling, except that wasm exception handling would allow the core code on the stack to catch the termination with |
We're definitely in the same realm of design space. And I'm also thinking from the perspectives of "I have some preexisting C code that calls exit(3)" and "I have some code that was written from scratch to be in a component". One constraint on the semantics we want, I think: It should be possible for an ordinary return from the entry point, and for a call to terminate deep in a call stack, to be externally the same. This is particularly relevant to the first use case I mentioned. We may want to allow termination to also look differently from the outside via some option or other mechanism, too. One reason that something like unwinding is appealing is that we may want to run atexit-style hooks, and so we need a place to return control to that is just short of actually exiting altogether. So unwinding just to that point, running some code, and then yielding control back to the host. Rather than just stopping execution altogether. I also suspect that the answer to this will come from the task and async perspective. |
And, just to confirm: is it our goal (or the ambient assumption of legacy code we need to uphold) to not run destructors when terminating (but do run And then, as a corollary of that: if we assume that the |
Yes and also: There's a couple sets of dtors to think about. One is for objects on the stack. The other is for globals, including TLS globals. It's worth keeping in mind, because I can imagine that unwinding per se is concerned with the first, and a libc-level runtime (the thing we want terminate to yield control to, just above the host) with the latter. Note also that https://en.cppreference.com/w/cpp/utility/program/quick_exit (also in C11) doesn't run TLS dtors. exit does. There's also handlers that run only at exit time but not quick_exit time. Neither exit nor quick_exit run stack object dtors. There's also state that is cleaned up in exit but not quick_exit, like stdio stream flushing, which aren't necessarily object dtors but can handled by the same runtime mechanisms. also cf rust-lang/rust#83994 for some of these things coming up in the rust stdlib context recently which may point at what kinds of things legacy code does (correctly or not). |
Eventually, this may be expressible via stack unwinding.
The text was updated successfully, but these errors were encountered: