We all have seen our Web browsers “unexpectedly close” and restart, which is usually more of an annoyance than a problem. However, if you are building embedded systems such as UAVs, car components, or medical devices, having your system unexpectedly close can have literally fatal consequences. For those kinds of applications, it is important that the software behaves correctly.
- GrammaTech CodeSonar Compliance with MISRA
- How to Avoid Common Pitfalls in MISRA Compliance
- ISO 26262 – A static analysis tools perspective
Dominance of C and C++
C and C++ are the dominant programming languages for embedded systems, due to easy access to hardware, low memory requirements, and efficient run-time performance. With these advantages, though, also comes some disadvantages. For instance, C and C++ have very limited run-time checking and a syntax in which mistakes may actually be technically legal expressions (for example: using & instead of &&). These challenges make C programs quite susceptible to serious memory-access defects such as buffer overruns or null pointer exceptions. Other classes of errors, such as resource leaks, use of uninitialized memory, and use-after-free errors, are also endemic and abundant in C programs. And when concurrency is used, defects such as data races and deadlocks are easy to introduce -- but frighteningly difficult to detect in development.
Emergence of MISRA
One of the best ways to achieve high-quality code is to follow a well-defined set of coding guidelines. With this in mind, in 1998, the UK's Motor Industry Software Reliability Association established a set of guidelines for the use of C in safety-critical systems. Following the 1998 set, MISRA's guidelines were updated and released in 2004 and 2014, with new rules, improved explanations, and better definitions to ensure correct containment of the C language and compliance to the standard. In 2008, MISRA released a set of guidelines for the use of C++ in critical systems.
Even if you are not required to conform to MISRA, you might want to consider adopting the guideline. After all, it is a way to write safer code that is more maintainable. Organizations like MISRA have spent years defining a coding standard and improving on it -- why would you invent your own?
MISRA is probably the most mature and widely-used coding standard. Like all coding standards, MISRA will not stop you from writing poorly-designed code, nor can it validate your algorithms. But it will protect you from the murky dark corners of the C/C++ language.
Some of the MISRA rules are easier to check than others. For example, Rule 15.5 states, “A function should have a single point of exit at the end," and it is easy to check for the exit in a function and make sure the exit is at the end. Other rules, such as Rule 5.3, “an identifier declared in an inner scope shall not hide an identifier declared in an outer scope,” are a bit trickier to detect. For rule 5.3, you need to analyze the scope of each identifier. Rules about run-time properties, such as rule 2.1, “There shall be no unreachable code,” can also be hard to check -- in some cases, the code path within a function can depend on the arguments passed.
Therefore, when choosing a static analysis tool to enforce MISRA compliance, you have to make sure that the tool can perform a deep analysis of the code, and analyze all the compilation units that contribute to the program.
Static Analysis Tools to Support MISRA
Once you have adopted a coding standard and set of rules for your development, you need to enforce the rules. This is where automated static code analysis tools like CodeSonar will help. CodeSonar checks for compliance to MISRA and other such standards; it also finds serious run-time errors statically. (Without automated tools, enforcement of a coding standard is likely to fail because humans are very bad at reliably detecting violations of these rules during code reviews.) By using CodeSonar, you can rely on its automated analyses to detect defects, security vulnerabilities, and non-compliance -- leaving you to focus on important functional elements, such as your algorithms.
There are several characteristics that should be considered when selecting a tool to check for coding standards:
- Complete dataflow and execution analysis. Tools that can find violations of syntactic rules, as well as problems that require deep semantic knowledge of the entire program, are necessary.
- Ability to enable/disable enforcement of certain rules. You also want the ability to define your own rules, in case you add some that are specific to your project, and disable other rules, if they are unrelated to your deployed environment.
- Presence of command-line version to seamlessly integrate the analysis in the build process. Tools should support existing build environments and not require radical changes to your existing tools and processes. Command-line versions also allow for nightly batch runs of the code checker to collect quality data.
- Comparison and report features. Knowing how the code quality progresses from build to build is essential in tracking the quality of your code.
- Detailed description and visible call path for warnings.
- Cost of ownership.
Adopting a coding standard such as MISRA, and a tool such as CodeSonar to enforce it, is a smart decision if you are looking to write safe, secure code. It is highly recommended for a productive and efficient development lifecycle, and will help decrease number of bugs and security risks.
Interested in reading more? Read the guide on
Accelerating Software Safety with MISRA and Static Analysis