4 ms·
The way I see it, there are a limited number of ways that a bare-metal component with no heap can "catastrophically fail": 1. "Undefined behavior" due to typic
by fleventynine 2y ago
The way I see it, there are a limited number of ways that a bare-metal component with no heap can "catastrophically fail":
1. "Undefined behavior" due to typical memory bugs: code written in 100% safe Rust cannot trigger this behavior.
2. "Undefined behavior" due to a stack overflow: this can happen in safe Rust, but you can provably guard against it by banning recursion and dynamic dispatch, and doing static stack depth analysis on your program.
3. Panic/abort: naively written bare-metal Rust typically has many potential calls to panic!() due to bounds checks, integer overflows, .unwrap(), etc, and if these get called the system will typically fail catastrophically. I like to solve this by having CI fail if the optimized binary contains ANY call-sites to the panic handler. This forces the developer to handle these edge cases with idiomatic error handling before they can merge their code (but can cause some development pain/brittleness when the optimizer heuristics change).
4. Infinite loops: in most bare metal systems, if a section of code doesn't complete within some reasonable time, a watchdog will fire and the system will crash. Ideally there would be some static analysis that could tell me whether some particular code is capable of exceeding the allotted time bounds, but I'm not aware of such tooling, and need to resort to hacky solutions such as fuzzing and handling resets "gracefully" at runtime.
- cdchn 2y ago>having CI fail if the optimized binary contains ANY call-sites to the panic handler. How do you do that?
- woodruffw 2y agoYou can use something like `no_panic`[1]. You could also do it statically, post-build, by looking for calls to the panic handler. [1]: https://docs.rs/no-panic/latest/no_panic/ https://docs.rs/no-panic/latest/no_panic/
- bpicolo 2y agoDoes annotating `main` with no_panic do the trick? How much does that tend to affect compile times, do you know?
- woodruffw 2y ago> Does annotating `main` with no_panic do the trick? I've never tried that, so maybe :-) > How much does that tend to affect compile times, do you know? IME, not very much -- there might be a small amount of overhead, but the "trick" behind the check is to fail the linker with a symbol error if the panic code is inserted into a function. So the compiler itself should be roughly as fast, and the error path in the linker is really the only thing that should change too much.
- fleventynine 2y agoHave your panic handler call an extern "C" function that doesn't exist, and the linker will complain if there's any calls to that function that weren't optimized out. Alternately, you can look for the symbol in the output elf file and fail if it's there, which is a bit more graceful as panicking binaries can still be produced during development.