Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

> Rust cannot recover.

catch_unwind exists for a reason.

> e.g. when you have an exception in a destructor then it's a guaranteed `std::terminate`.

You can throw in a destructor [1]. You just need to mark that destructor noexcept(false). You do get a guaranteed std::terminate if an exception escapes a destructor while unwinding is already underway, though.

> Do note that C did not have such a flaw built into language

assert() says hi?

> I mean specially designed embedded C code can survive total RAM erasure and still perform some meaningful work (with CPU registers and ROM intact).

Why doesn't a similar argument apply to "specially designed" Rust?

> Or compare it to BEAM that can have processes crash all day long and still continue to work.

Again, nothing stops you from writing Rust that does the same.

[0]: https://doc.rust-lang.org/std/panic/fn.catch_unwind.html

[1]: https://cpp.godbolt.org/z/ao4cf3zrr



>You can throw in a destructor [1]. You just need to mark that destructor noexcept(false). You do get a guaranteed std::terminate if an exception escapes a destructor while unwinding is already underway, though.

Come on, please tell me you don't do this in your code. Formally you are correct, but there are many things in C++ that should have better not existed.

>Why doesn't a similar argument apply to "specially designed" Rust?

Because it would lose most of the Rust properties by that time. C code with fixed memory layout, on the other hand, is ideomatic and was widely employed in the past. It's still being employed in embedded. I'm not saying that you are wrong though, there might be people optimizing Rust for this very purpose, but I'm not aware of such an effort.

>catch_unwind exists for a reason.

>>Or compare it to BEAM that can have processes crash all day long and still continue to work.

>Again, nothing stops you from writing Rust that does the same.

Who's gonna GC the poisoned garbage left in undefined state after the crash? I'm not saying it's impossible — I honestly have no idea whether safe recover is possible in Rust, but from what I know it's rather in middle of "not possible" and "not viable".


> Come on, please tell me you don't do this in your code.

I don't, but that's not to say that I think it should never be done.

> Formally you are correct, but there are many things in C++ that should have better not existed.

Sure, but I think it's important that one should do their best to be correct and/or precise.

> Because it would lose most of the Rust properties by that time.

Perhaps for specific bits of code, but that doesn't necessarily require that your entire codebase give up on safety. Part of Rust's value is in isolating unsafe stuff to specific sections of your codebase both so the rest of the code can make use of Rust's guarantees and so if/when something goes wrong it's easier to pinpoint the problem.

Not to mention if you're talking about "specially designed" codebases in the kind of situation you describe you're almost certainly not in pure-C-land either (e.g., standard C doesn't have the concept of CPU registers, so if you really need to stick to what's in registers you're going to have to resort to compiler-specific extensions and/or assembly). If you're willing to allow the necessary extensions for C, it's only fair that you do the same for Rust.

> I'm not saying that you are wrong though, there might be people optimizing Rust for this very purpose, but I'm not aware of such an effort.

There's a reason no_std exists. Low-resource embedded use has been a design focus since well before Rust's 1.0, and those considerations have continued to influence its evolution since - for example, Rust's async design is the way it is specifically to ensure it is usable in limited-resource environments.

> Who's gonna GC the poisoned garbage left in undefined state after the crash?

Whatever supervising process/thread you write/designate, if that kind of recovery is important to you? I don't think there's anything about Rust that precludes you writing such a thing.

Not to mention, must there be "poisoned garbage" in the first place? I don't think it's strictly necessary that such a thing be produced after a crash even if you ignore the fact that part of the reason unwinding exists is to clean things up even while crashing.

> but from what I know it's rather in middle of "not possible" and "not viable".

I'm curious how you came to that conclusion. It seems wrong both on a theoretical level (Drop/unwinding/catch_unwind should obviously suffice for at least some cases?) and on a practical level (tokio can recover from worker thread panics just fine?).


>I'm curious how you came to that conclusion. It seems wrong both on a theoretical level (Drop/unwinding/catch_unwind should obviously suffice for at least some cases?) and on a practical level (tokio can recover from worker thread panics just fine?).

Tokio provides crash-resistant synchronization primitives, but it cannot recover complex structures you've been handling — you either need to write panic-handlers that would revert your data to more-or-less manageable state or employ ready-made libs that do it for you. Languages designed for crashes don't require ad-hoc recovering — they just automatically clean up everything. That's what I've called "viable".

I mean you could have written crash recovery in C++, but it's just not viable because of how many things can go wrong.


> Tokio provides crash-resistant synchronization primitives, but it cannot recover complex structures you've been handling — you either need to write panic-handlers that would revert your data to more-or-less manageable state or employ ready-made libs that do it for you. Languages designed for crashes don't require ad-hoc recovering — they just automatically clean up everything. That's what I've called "viable".

Maybe I'm a bit confused, or I haven't made my point clear enough. I'm not trying to say that Rust will clean up errors in the same way languages like Erlang do. I'm saying that you can write Rust that will clean up errors in the same way languages like Erlang do. In short, what I'm protesting is the absoluteness of the claims.

That being said, I also feel like you're comparing apples and oranges to some extent here. I don't think the more complex recovery you're describing in the Tokio example is the same thing as the cleanup you describe "languages designed for crashes" as implementing. I think the cleanup you describe "languages designed for crashes" as implementing is "weaker" (in a CS theoretical sense) than the more complex manual recovery you describe as being required when using Tokio, which means you still need to write said more complex manual recovery even in languages like Erlang.

For example, consider this email from Joe Armstrong [0]:

> In C etc. you have to write *something* if you detect an error - in Erlang it's easy - don't even bother to write code that checks for errors - "just let it crash".

> Then write a *independent* process that observes the crashes (a linked process) - the independent process should try to correct the error, if it can't correct the error it should crash (same principle) - each monitor should try a simpler error recovery strategy - until finally the error is fixed (this is the principle behind the error recovery tree behaviour).

At least from how I read this, there's no fully "automatic[] clean up"; you still need to write the moral equivalent of "panic-handlers that would revert your data to more-or-less manageable state or employ ready-made libs that do it for you". Erlang/BEAM/etc. is not going to automatically correct errors for you in all possible cases - if it were, there would be no need to write that yourself - so I don't think it's reasonable to expect that from Rust either.

In addition, nothing here jumps out to me as being impossible to implement in Rust. Use nested threads, use catch_unwind to stop unwinding from killing the entire process, write appropriate panic handlers, etc. and you should get a similar result.

Perhaps you had a different example in mind?

[0]: https://erlang.org/pipermail/erlang-questions/2003-March/007...




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: