Some Boeing 737s can't land on some runways with true heading 270 [pdf]
rgl.faa.gov
rgl.faa.gov
This issue looks to be a pretty run-of-the-mill bug in their software. It's likewise scoped down pretty far--there only exist a few runways (in US, Colombia, and Guayana) that make this relevant. ADs like this come out all the time.
As to why the bug exists, who knows :)
Edit: Clarified slightly.
The FAA routinely issues airworthiness directives for all sorts of safety issues. Here are a few others published in the past week or so:
https://rgl.faa.gov/Regulatory_and_Guidance_Library/rgad.nsf...
https://rgl.faa.gov/Regulatory_and_Guidance_Library/rgad.nsf...
https://rgl.faa.gov/Regulatory_and_Guidance_Library/rgad.nsf...
https://rgl.faa.gov/Regulatory_and_Guidance_Library/rgad.nsf...
The problem with such “partial” functionality is that it breaks composition. When you start building systems with a dozen modules, each with a couple of edge cases like this, the probability of something failing becomes high, and makes the final result/experience very crappy. Imagine if you had a sweater you couldn’t wear on Tuesdays!
For those who don’t get it, it’s not just about how often this “bug” affects the system (let alone the fact that it is quite severe). It indicates an utter lack of competence towards developing safety critical systems... like, how can one be writing navigation code and NOT know this?
That this could be considered a run-of-the-mill software bug means that we have set our standards too low.
Undefined. The problem was never a lack of technical proficiency, the problem is the culture.
In 2007 squadron (12) of F-22's were flying from Hawaii to Japan. When they crossed when they crossed international date line every plane had systems crash. They lost communication-, fuel-, and navigation subsystems and restart did not solve the problem. Apparently only basic aviation systems worked. They could still fly.
They would have been completely lost, but luckily tanker escorting them was still nearby. They were able to follow it back to the base.
Holy f-cking f-ck.
And if not the compiler, are there popular static analyzers for any languages that do so?
My probably wrong understanding is that the philosophy behind Rust is that code without IO/unsafe shall not panic. It might provide useless results but it won't panic. But dividing an integer by zero causes a panic (if I recall).
Edit: derp. Of course they can panic. You really can't guard against overflow or OOM and such. gpm helped correct my thinking: it's not about avoiding panics, it's about avoiding undefined behaviour, forcing you to define all possible branching paths.
What safe code isn't allowed to result in is undefined behavior. Panics are defined, they just happen to be defined to print an error message and abort the program (by default, slightly simplified version of how they work).
By the way: If you want to handle overflows you can use methods like `checked_add`, or you could do something like the suggestion for division by zero and create a wrapper type that always does `CheckedI32 + CheckedI32 -> Option<CheckedI32>` (or something). I might implement `Option<CheckedI32> + Option<CheckedI32> -> Option<CheckedI32>` as well so you can delay checking for overflow/division by zero until you want to use the result of the arithmetic.
What I am reading from this is that in Rust, debug assertions cause a different semantics. That does not sound right at all.
Assertions, check if a condition is true, and if it is false print an error message and exit the program. Assertions in rust are written `assert!(expr, optional_formatting_stuff)`.
Debug assertions do the same, but they are only executed when the `debug_assertions` flag is passed to the compiler, typically for performance reasons. In C terms, a debug assert is basically `#ifdef DEBUG_ASSERRTIONS assert(foo) #endif`. Debug assertiosn in rust are written `debug_assert!(expression, optional_formatting_stuff)`.
"Formally", arithmetic overflow in rust is defined to either wrap (as per 2s complement arithmetic) or panic.
In todays compilers that means they perform 2s complement artihmetic when debug assertions are turned off, and they panic when it is turned on. If performance of checking for overflows improves in the future, it will be considered an acceptable (backwards compatible) change to always panic instead, but that would have too large a performance impact today.
For example, if you do "u32::INTEGER_MAX + 3" in debug, it will panic, but in production code it will not (and will use the underlying CPU's result of "2")
In most scenarios, this is not actually what you want. If your program has the possibility of doing arithmetic near or past the bounds, you should define the semantics you need.
I.e., you can use one of saturating_add, wrapping_add, checked_add, or overflowing_add, depending on the semantics that are correct for your application. All of these behave the same between dev and prod.
error: attempt to divide by zero
--> main.rs:2:16
|
2 | let result = 1 / 0;
| ^^^^^
|
= note: #[deny(const_err)] on by default
error: this expression will panic at runtime
--> main.rs:2:16
|
2 | let result = 1 / 0;
| ^^^^^ attempt to divide by zero
error: aborting due to 2 previous errors
very simple example though, no idea what happens when that value comes via socket or file, guess that would panic! then.And yep, the result is a panic, even with debug_assertions off (i.e. you make overflows wrap instead of panic).
https://play.rust-lang.org/?version=stable&mode=release&edit...
For x86, you would get an exception. Of course the compiler could insert a check for 0 and a branch, avoiding the exception.
For PowerPC and I believe most RISC, there is no exception. Most processors would give a specific value, such as 0x80000000 for 32-bit. Of course the compiler could insert a check for 0 and a branch, intentionally jumping to code that raises an exception.
On MIPS the convention was exactly that. The compiler would add that extra code so that you'd get an exception even though the hardware wouldn't give one.
This often causes RISC processor emulators compiled for x86 to crash.
It's one of the many architecture-specific things that can poke through the abstraction layers to burn people. Another common group of them, for which I'm curious what rust does, is shift values that are out of range or that shift negative values right. For example: -6 shifted right by 1, 42 shifted left by 4096, 12 shifted right by -2, 88 shifted left by -3, -13 shifted right by 256, etc. (and for the non-negative values, does it matter if they are an unsigned type or not?)
https://play.rust-lang.org/?version=stable&mode=debug&editio...
If you go poking around geometric code (cartography, computational geometry, physics modeling, graphics, ...) and hunt for places where trigonometry is used, you’ll find lots of errors where the programmer didn’t consider the behavior in every edge case. The vector alternatives are simpler, more efficient, more numerically stable, and a lot easier to reason about.
subtype Heading is Integer range 1 .. 360; type Heading is mod 360;