Live data from Hacker News

No-Panic Rust: A Nice Technique for Systems Programming

blog.reverberate.org

91–100 of 143 posts

Re: No-Panic Rust: A Nice Technique for Systems Programming

#91

Earlier quoted context omitted.

https://doc.rust-lang.org/book/ch09-01-unrecoverable-errors-... ``` [profile.release] panic = 'abort' ```

After using rust for several years, I'm shocked this isn't the default. Making panics recoverable leads to them being used incorrectly.

Panics also unwind the stack and run all your Drop destructors.

Setting `panic = abort` disables unwinding and this means leaking memory, not closing file descriptors, not unlocking mutexes and not rolling back database transactions on panic. It's fine for some applications to leave this to the operating system on process exit but I would argue that the default unwinding behavior is better for typical userspace applications.

Re: No-Panic Rust: A Nice Technique for Systems Programming

#93
post #6
post #2

This website makes by browser freeze... No idea why. Not able to read the article.

Author here -- that is surprising. What browser/OS are you on? I haven't had anyone else report this problem before.

Same here: Chrome on a Google Pixel 4a. Page freezes while scrolling down and eventually oh-snaps.

Re: No-Panic Rust: A Nice Technique for Systems Programming

#94

Earlier quoted context omitted.

Panic-analyzer looks like it is based on heuristics, searching for known-panicing APIs. I tried it on a workspace that uses io::stdout() and it did not flag this as potentially panicing. No-panic looks nifty: it appears to be reliable, which is great. I wish there was an easy way to automatically apply this annotation to every single function in a given file or crate.

I think the article is wrong in that std::io::stdout would be panicking, or that "the panic is reachable somehow". It's just the optimizer doesn't see it doesn't panic. https://doc.rust-lang.org/beta/src/std/io/stdio.rs.html#674-... The implementation calls indeed a panicking API, OnceLock::get_or_init: https://doc.rust-lang.org/beta/std/sync/struct.OnceLock.html... But it only panicks if it is being used in a wrong…

If the only problem was OnceLock, the simplest solution would be to replace it with a const initializer.

The main reason getting panic-free stdout is hard, is that the STDOUT initializers both call allocating constructors, and LineWriter doesn't have non-allocating constructors.

Solving this elegantly seems hard.

Re: No-Panic Rust: A Nice Technique for Systems Programming

#96
post #31

Earlier quoted context omitted.

that just makes the panics unrecoverable. It doesn't statically guarantee no panics.

There is no-panic [1] to turn panics in a function into compile errors, or the older no-panics-whatsoever [2] to do the same for the entire binary 1: https://crates.io/crates/no-panic 2: https://crates.io/crates/no-panics-whatsoever

no-panic uses link-time shenanigans to prevent panics in the compiled binary, but this isn't 100% reliable (as explained in the README, just pointing this out)

Re: No-Panic Rust: A Nice Technique for Systems Programming

#97
post #79

Earlier quoted context omitted.

The program can detect invalid state, but your intention was to never get to that state in the first place. The fact that the program arrived there is a Logic error in your program. No amount of runtime shenanigans can repair it because the error exists without your knowledge of where it came from. You just know it's invalid state and you made a mistake in your code. The best way to handle this is to crash the progra…

> The fact that the program arrived there is a Logic error in your program. No, your program correctly determined that user input was invalid. Or your parser backtracked from parsing a Bool and decided to try to parse an Int instead.

That’s not invalid state. Your program correctly determined input is invalid.

Say user input is a number and can never exceed 5. If the user input exceeds 5 your program should handle that gracefully. This is not invalid state. It is handling invalid input while remaining in valid state.

Let say it does exceed 5 and You forget to check that it should never exceeds 5 and this leads to a division by zero further down your program. You never intended for this to happen and you don’t k ow why this happened. This is invalid state.

Now either this division by zero leads to an error value or it can throw an exception. It doesn’t matter. Do you know how to recover? You don’t even know where the bug is. A lot of times your don’t even know what to do. This error can bubble up all the way to main and now what do you do with it?

You crash the program. Or you can put in a fail safe before the error bubbles up to main and do something else but now (if your program retains and mutates that state) has invalid values in it and a known bug as well.

Imagine that input number represented enumeration values for movement of some robot. You now have one movement that doesn’t exist or was supposed to be something else. Thus if you keep your program running the robot ends up in an unexpected and erroneous place. That’s why I’m saying a program should crash. It should not be allowed to continue running with invalid state.

Like imagine if this was a mission critical auto pilot and you detect negative 45 meters for altitude. Bro crash and restart. Don’t try to keep that program running by doing something crazy in attempt to make the altitude positive and correct. Reset it and hope it never goes to the invalid state again.

Re: No-Panic Rust: A Nice Technique for Systems Programming

#98
post #85

Why worry about the code size if the code size is up to the library consumer (through their choice of panic handler)? If the consumer worries about code size, then their application has a minimal panic handler. If the consuming application does not have a minimal panic handler, then it must not worry about code size? Is there some context I'm missing here? Is this to be used from non-Rust applications for example?

As the author mentions, `panic!` is also not an acceptable failure mode in some applications. If you're developing safety-critical software and a process stopping is part of your risk analysis, many frameworks will ask you about the frequency of that happening. In that analysis, you may be required to set all systematic contributions to that frequency to zero. This happens, for example, if you try to control the asso…

Yes that condition I understand. But that seems orthogonal to the code size issue. Having no panics in code where the stdlib is riddled with panics for exceptional situations (allocation failure, for example) seems like a situation where you would just always go with no_std?

Re: No-Panic Rust: A Nice Technique for Systems Programming

#99

Earlier quoted context omitted.

An assert is just a fancy `if condition { panic(message) }`. If the optimizer can show that condition is always false, the panic is declared as dead code and eliminated. The post uses that to get the compiler to remove all panics to reduce the binary size. But you can also just check if panic code was generated (or associated code linked in), and if it was then the optimizer wasn't able to show that your assert can't…

Ah, I see what you are saying. Yes, if the optimizer is able to eliminate the postcondition check, I agree that it would constitute a proof that the code upholds the invariant. The big question is how much real-world code the optimizer would be capable of "solving" in this way. I wonder if most algorithms would eventually be solvable if you keep breaking them down into smaller pieces. Or if some would have some step…

I wonder if there is a simple way to stop compilation quickly, with a readable error message, if the optimizer isn't able to eliminate the check.

edit: There is https://github.com/dtolnay/no-panic

Re: No-Panic Rust: A Nice Technique for Systems Programming

#100
> Unrecoverable

panics are very much designed to be recoverable at some well defined boundaries (e.g. the request handler of a web server, a thread in a thread pool etc.)

this is where most of it's overhead comes from

you can use panic=abort setting to abort on panics and there is a funny (but unpractical) hack with which somewhat can make sure that no not-dead-code-eliminated code path can hit a panic (you link the panic->abort handler to a invalid symbol)

Post reply on HN