8 ms·
Rules for Developing Safety Critical Code [pdf]
- deleted 12y ago[deleted]
- jokoon 12y agoI would gladly print that PDF and stick it in every office. Maybe an alternative would be to make it work, and then to make it readable.
- qwerta 12y agoThis paper also explains each rule. They use code analysis tools a lot, and do not like stuff which makes analysis harder (recursion, unbounded loops..)
- john_b 12y agoRecursion and unbounded loops are far too risky on their own, even ignoring the problems they cause for static analysis. The code that goes on NASA spacecraft is bombarded by cosmic rays on a daily basis, something a server sitting in a building at the bottom of the atmosphere doesn't have to worry about nearly as much. Even if the code is perfect, if a ray hits the right spot it's possible for it to flip a bit and then your perfect recursive function will do who knows what. [1] They use error-correcting memory to combat this, but it's still better to be safe than sorry when your software controls a multimillion dollar space oasis with human beings inside who have no means of escape. [1] http://www.statemaster.com/encyclopedia/Single_event-upset http://www.statemaster.com/encyclopedia/Single_event-upset
- jordanpg 12y ago> All code must be compiled, from the first day of development, with all compiler warnings enabled at the compiler’s most pedantic setting. All code must compile with these setting without any warnings. All code must be checked daily with at least one, but preferably more than one, state-of-the-art static source code analyzer and should pass the analyses with zero warnings. Wow, am I ever frustrated by the summary ignoring of warnings I see going on around me. I spend my spare time at work making warnings go away and deleting uncommented @SupressWarnings from our codebase. In a word, KISS. Another engineer designing critical systems for the US government coined that one, apparently [1]. [1] http://en.wikipedia.org/wiki/KISS_principle http://en.wikipedia.org/wiki/KISS_principle
- jokoon 12y agoKISS needs to be taught, I really feel there should be a political movement around this principle. Maybe one good exercise would be to ask programmers to write some program, and then let people vote on which code is the simplest to read and to understand.
- bprs 12y agoAny recommendation of a good static source code analyzer for C++ ?
- RogerL 12y agoPVS Studio has always seemed to catch the most errors for me. It is by far worth the price if you s/w is at all important to you. But no tool is perfect. I also run cppcheck, Microsoft's VS (never liked that one much). Haven't tried Clang because I am on Windows for my C++ stuff.
- AndreyKarpov 12y agoUpdatable List of Open-Source Projects Checked with PVS-Studio: http://www.viva64.com/en/a/0084/ http://www.viva64.com/en/a/0084/
- raverbashing 12y agoOf course, this is not as simple as it seems. 1 - Some tools and libraries (like GTK - yeah) like to throw unfixable warnings. "Yeah, this platform is missing this feature so let's throw a warning" 2 - Sometimes fixing a warning results in something much more complicated than the original code. (see for example half of PyLint warnings) So, for that to work it's important the tool warnings are good (and at least with GCC on C they usually are)
- RogerL 12y agoWhen I did mission critical work we basically did not use libraries if at all possible. You need to know how everything works, and you need to be able to fix it. I'm pretty sure the NASA paper is written within that context. But yes, that is a huge pet peeve of mine. I have all my QT header includes wrapped with pragmas to turn off warning because otherwise they spit out endless, useless warnings.
- kikki 12y agoSo basically keep code simple, concise, and predictable.
- volent 12y agoThe rule about pointer is pretty limiting (no pointer function, no more than one level of dereferencing). The reason is also pretty sad : "Pointers are easily misused, even by experienced programmers". I don't see how an experienced programmer has more chance to misuse pointers than anything else.
- TeMPOraL 12y agoI believe this is because of the type of code they write. When writing real time systems you care about predictability of execution. When you allow function pointers, you (as a programmer / static analysis tool) suddenly have no idea what code will be executed, thus you can't reason about the time it takes. You could scour the codebase for all instances of code that set a particular function pointer, but then again it might be done indirectly, or - heaven forbid - based directly on external input. It makes code much harder to reason about.
- pjc50 12y agoThis. There are categories of embedded system that don't allow reentrancy; it must be possible to represent the program's callgraph as a DAG with each function appearing exactly once. In some systems (ADA?) this allows for the preallocation of all local variables, too. Some hardware (e.g. the smaller PICs) has poor support for pointers which can make indirection cost quite a lot of instructions. Then there's the general principle of cutting your coat according to your cloth. You don't use a generalised pointer-to-rocket-engine system because you aren't going to add more engines at runtime
- termain 12y ago"You don't use a generalised pointer-to-rocket-engine system because you aren't going to add more engines at runtime" Well, we might. Particularly if the vehicle you're modeling for a hardware in the loop sim isn't entirely specified at compile time.
- jordanpg 12y agoThe problem is really the redirection. The guiding principle of this document is wrapping every single functional block in a self-contained, statically-analyzable function. If there is anything that pointers must be used for, then they must be used. But it is hardly controversial to say that pointers are one of the least-well understood and frequently misused aspects of low-level programming.
- laurencei 12y ago> Typically, this means no more than about 60 lines of code per function. Uncle Bob would be very upset by this statement. He advocates a maximum of 4-5 lines per function to ensure readable code in his Clean Coders video series. Anything more, and you need to refactor into smaller functions.
- zoner 12y agoThat was a loose statement in the book, 60 lines might be long, but in extreme cases, it's ok.
- brudgers 12y agoPerhaps Uncle Bob is engineering for the real world and applying 10 as the factor of safety. Space flight engineering runs more thinnly along the envelop. With the JPL Standard's requirement that all functions validate every argument, one line per declaration, and two assertions on average per function, six lines will disappear pretty fast. Uncle Bob is preaching software engineering as engineering to the heathen masses. The JPL Standards are a sermon for the choir. Uncle Bob doesn't, so far as I know, advocate C for all critical code.
- anton_gogolev 12y ago> He advocates a maximum of 4-5 lines per function to ensure readable code Yeah, and you end up with myriad of functions which are used once and only once and it becomes impossible to actually find code which does something useful.
- nly 12y ago... and good luck naming all those functions.
- pjc50 12y agoSee sibling comment about domain-specific language; there's nothing wrong with long function names if your autocomplete is working. Codebase I'm working with has names like "auditNullRecipeCursorAtEndOfOrderLineAdditionsIfRequired" and "getUnselectedSiblingWithSametabIndexOrCreateRepeatedChildIfLessThanMax"
- tgb 12y agoThe most impressive thing I've read about NASA's software development isn't mentioned here. It was the system where bugs and defects were (at least in principle) not treated as the failing of an individual but rather as a failing of the entire development process. So when a problem is found, the question isn't "Who did this and how can we punish them?" it's "What can we as a team do so that this never happens again?" I don't know how this works in practice, but it sounds like a great system even when dealing with code in a lower-risk setting.
- jordanpg 12y agoThis is just an attribute of good leadership. It's applicable to teams in any context, and can't be enforced except by leaders who themselves are led by strong leaders.
- jwdunne 12y agoActually, the use for that doesn't seem restricted to software in general. It seems like you could apply that to any team and get better results - for example, if a big sales deal falls through, don't punish the sales person, use the situation as a learning experience. I try to do this with my team as much as possible. I am limited by my superiors, who don't hold the same beliefs about maintaining morale and intrinsic motivation.
- pilsetnieks 12y agoIt is also known as kaizen, with the Toyota Production System[1] as the best known example. [1] https://en.wikipedia.org/wiki/Toyota_Production_System https://en.wikipedia.org/wiki/Toyota_Production_System
- Swizec 12y agoThis ... is how it should be? Is this not obvious to everyone? When push comes to shove, it doesn't matter who made a mistake, all that matters is that things didn't work. And that's all you really care about. The result. People make mistakes. But systems let mistakes into production.
- tempodox 12y agoThe PDF file seems to be timestamped 2014-12-26. Does any-one happen to know the exact authoring date? Sadly, there is no date given in the document itself.
- atsaloli 12y agoThe PDF is based on the article ''The Power of Ten -- Rules for Developing Safety Critical Code,'' in IEEE Computer magazine, June 2006, pp. 93-95 Source: author's website http://spinroot.com/p10/ http://spinroot.com/p10/
- JNRowe 12y agoatsaloli already gave a good answer, but I'll add that the date is in the PDF's metadata. fex, poppler provides pdfinfo which shows the creation date of 2007-01-15. Your viewer probably has an option to show it too.
- tempodox 12y agoIndeed, you're right. Even Apple's Preview app on my box can do that :)
- dimman 12y agoA bit surprised it doesn't mention the use of curly braces. Perhaps they assume their "state of the art" static code analysis tools will find potential issues (like Apple's goto fail failure).
- TorKlingberg 12y agoThis documents is a summary. There in much more detail in the JPL Institutional Coding Standard for the C Programming Language : http://lars-lab.jpl.nasa.gov/JPL_Coding_Standard_C.pdf http://lars-lab.jpl.nasa.gov/JPL_Coding_Standard_C.pdf
- gchp 12y agoPerhaps due to the context of this link, I read "Apple" as "Apollo"
- bluedino 12y agoWe just talked about this: https://news.ycombinator.com/item?id=8856226 https://news.ycombinator.com/item?id=8856226
- deleted 12y ago[deleted]
- kibwen 12y agoI'm interested by the rule that says that loops must either be statically verified to terminate or statically verified to never terminate. Combined with the forbidding of recursion, it's an interesting approximation of a non-Turing-complete language. Or are guaranteed-to-be-infinite loops admissible in non-Turing-complete languages?
- wyager 12y agoYou are correct. Total languages are not Turing complete. However, in the case of safety-critical software, we don't actually follow that rule perfectly. We usually have one or more main loops that never terminates, but everything called from there does terminate. In languages that enforce totality, like Agda (which is not suitable for most safety-critical programming), you can either selectively disable termination checking on the main function, or you can recurse over a large number. I'm partial to 99999999999999999.
- getpost 12y ago// Of course this is only an example, but except in rare cases when the value of a boolean is significant (e.g., interfacing code in different languages), don't compare to booleans! Not only is it redundant, it's another potential source of error. if (!c_assert(p >= 0) == true) { return ERROR; } // vs if (!c_assert(p >= 0)) { return ERROR; } // The following makes the error condition clearer, but it goes against the convention of having a hopefully true condition as the argument to assert. if (c_assert(p < 0)) { return ERROR; }
- asynchronous13 12y agoI agree with you in principal, but in practice I work on a lot of C code that does not have a built in bool type (C89). In your example using > or < there is not an issue because it's certain the return value is either 0 or 1. However, when checking a specific variable used as a boolean I prefer to see an explicit comparison. if(variable) versus if(variable==TRUE) I developed this preference after spending weeks on a particularly nasty bug. The bug was triggered by a corrupted int that was used as a boolean variable that passed a check because if(146134613) { kill_me_now(); } will run, even though the value had been corrupted. (of course, tracking down the source of the corruption was the real fix for that case, but there's no point in having safety checks that don't work)
- getpost 12y agoInteresting example, but then you're at risk of creating code paths that vary depending on whether boolean values are true, false, or other, which is contrary to the definition of a boolean value.
- asynchronous13 12y agoYou're right, but that is true because there is not a boolean type, not because of the form of the check. Either form has the same problem since an int is used in place of a true boolean (true | false | other), but I prefer the form that makes it more explicit and noticeable.