Siriporn Kaenseeya | Dreamstime.com
Programmer Promo 60352a5210e76

Defeat Defects with Safety Coding Techniques

March 18, 2021
The move from mechanical processes to high-level programming languages has ushered in numerous unknown side effects leading to defects. Thus the need for coding standards to help future-proof your code and ensure ease of reuse.

This article series is in the Improving Software Code Quality topic within our Series Library

What you'll learn:

  • Key safety-focused software coding standards.
  • How automated tools are used to implement safety coding techniques.

The modernization of programming languages and the importance of better coding techniques is directly related to the evolution from mechanical computers to modern software-development processes. We moved from a highly specialized, mostly mathematical, notation to high-level programming language close to human syntax.1 While this was made possible by compiler technologies, it opened the door to defects.

High-level programming languages like C and C++ contain an enormous number of undefined behaviors that various compilers may interpret slightly differently. This can cause unknown or unwanted side effects that will translate into defects.

Detecting and fixing defects can take up to 80% of the development time, depending on the maturity of the development organization. Obviously, code quality is a huge concern. Why not avoid the defects and significantly reduce debugging time?

On a side note, the terms bugsand debugging in software originally came from Harvard University's mechanical computers. A moth became stuck in a relay and the event was documented as the first system defect or bugin computer history.

Our Definition of Insanity: Repeating the Same Mistakes Again and Again

A number of respectable institutions like NASA, Bell Labs, and MITRE conducted several surveys and studies that led to the same conclusion: Developers in web, apps, desktop, or embedded tend to inject, accidentally, the same kind of mistakes into their source code repeatedly.

Examples of these common errors include allocations without deallocations in C++ code (or even in C code) and functions used without prototyping, so you dont get rigorous type-checking at compile time. In addition to identifying these commonalities, the research identified lists of best or recommended programming practices that pinpoint and help prevent risky and bad coding behavior.

Some best practices have been defined as well-known standards, e.g., MISRA C and CERT C. These are especially in critical in ensuring code safety and security in applications used in industries like transportation and healthcare.

Functional safety standards such as IEC 61508,2 EN 50128,3 and ISO 262624 recommend (or highly recommend, depending on the safety integrity level (SIL) or Automotive Safety Integrity Level (ASIL)) the use of static- and runtime-analysis tools to be compliant with the standards. Defects in safety-critical systems could lead to severe consequences such as loss of lives or environmental damage.

Focus on Reliability

Safety coding techniques represent the combination of code quality, code safety, and code security. Code safety focuses on the reliability of the software, while code security is all about preventing unwanted activity and keeping the system secure during an attack. Both rely heavily on the code quality thats the foundation of every solid application.

While safety coding techniques and standards drive software safety to ensure the needed reliability, its crucial to also enhance readability and maintainability of the source code. More efficient and readable code means future-proofing the source code with less defects and making the reuse of code possible.

MISRA C is one of the most well-established software-development standards designed to aid in avoiding common pitfalls and vulnerabilities. However, additional guidelines like CWE (Common Weakness Enumeration) and the CERT C coding standard are highly recommended for any embedded application.

The MISRA C Standard

MISRA C was developed by the Motor Industry Software Reliability Association. Its aims are to facilitate code safety, portability, and reliability in the context of embedded systems, specifically those systems programmed in ISO C.

The first edition of the MISRA C standard, "Guidelines for the use of the C language in vehicle based software,was produced in 1998, and is officially known as MISRA C:1998. It was updated in 2004 and again in 2012 to add more rules. Theres also the MISRA C++ 2008 standard based on C++ 2003. Lately, MISRA C:2012, Amendment 1 adds 14 additional rules with a focus on security concerns highlighted by the ISO C Secure Guidelines. Several of these rules address specific issues pertaining to the use of untrustworthy data, a well-known security vulnerability in many embedded applications.

MISRA helps you find issues before you check code into a formal build, so finding a bug this way makes it like the defect never happened. MISRA rules areagaindesigned with safety and reliability in mind, but they also make code more portable to other tools and architectures. 

CWE and CERT C/C++

CWE is a community-developed dictionary of software weakness types. CWE provides a unified, measurable set of software weaknesses to better understand and manage them as well as enable efficient software security tools and services that can find them.

The CERT C/C++ Secure Coding Standards are standards published by the Computer Emergency Response Team (CERT). They provide rules and recommendations for secure coding in the C/C++ programming languages.

Enforcing Safety Coding Techniques

As a general recommendation, every embedded application minimally should follow the CWE and CERT C/C++ standards. MISRA C is mandatory for safety-critical systems.

Following the same concept, during runtime you can still be susceptible to arithmetic issues, buffer overflow, bounds issues, heap integrity, and memory leaks. Such errors can be detected by inserting specific instrumentation code or asserts at all places where a potential error can happen. However, adding instructions manually to check the condition and somehow report the issue at runtime is a very time-consuming task.

Applying all guidelines and standards means that you need to be compliant with almost 700 rules and requirements in addition to instrumenting your code. So, how can you enforce the safety coding techniques and keep up with all of the rules?

Use Automated Tools

The best way to enforce software quality, safety, and security is to use automated tools. This can be achieved with the use of a high-quality compiler and linker that are preferably functional-safety certified and combined with automated static analysis and runtime analysis.

The compiler and linker should support a modern programming language like the latest C (ISO/IEC 9899:2018) and C++ (ISO/IEC 14882, known as C++ with the latest C++17 revision). Therefore, they can generate warnings for suspicious situations or for syntax weaknesses, e.g., volatile memory access whose order of evaluation could affect the logic of the application.

Warnings are your first-pass static-analysis check and should never be ignored, particularly in a functional-safety setting. The best recommendation is to turn the warnings into errors by changing the compiler settings to treat all warnings as errors. This will force the developers to fix all ambiguities in the code, since all issues will be handled as genuine problems.

Static-analysis tools help you locate the most common sources of defects in your code. However, they also help find problems that developers tend to not think or worry about when trying to write their code, especially when theyre just putting up scaffold code to get something working.

Such tools really aid in developing better code because they enforce the coding standards. In addition, dynamic or runtime-analysis tools catch and trigger defects that only pop up during runtime. A runtime-analysis tool can find real and potential errors in the code while executing the program in a software debugger.

So, when you look at all of the defects that could be in your system, static analysis is good at finding some defects and runtime analysis is good at pinpointing others.  Sometimes theres overlap, but in other instances a defect can only be detected in one domain or the other. To get the best possible code analysis, you need to use both in conjunction with another and integrated with your top-notch build tools. The matrix (Fig. 1) best represents the complete defect coverage when combining the different tools.

Catching Loopholes

This effect can best be explained in Figure 2, taken from University Bielefeld in Germany.5 This photo was taken by an anonymous contributor and circulated widely in 2005.

The easiest way to break a system is often to circumvent it rather than defeat it. This is mostly the case with software vulnerabilities connected to insecure coding practices. The image in Figure 2 is a great analogy for thisthe gate is in place per the recommendations and is functioning appropriately according to the specifications. However, the security measure was easily bypassed and until a runtime-analysis tool was in place (in this case, snow), it was probably difficult to spot the flaw in the security system. Automated runtime analysis that scans your code for potential loopholes is a great way to detect these types of issues.

In this case, the safety vulnerability was fixed in hardware, namely the installation of concrete bollards according to Google Street View in 2020 (Fig. 3).

Coding standards help to future-proof your code and ensure ease of reuse. This means the codes quality affects the codes reusability and this is what mature organizations have in their culture when developing new products. Its a virtuous cycle to enforce the safety coding techniques and it reaffirms our premise: Everything simply starts with code quality.

Read more from the Improving Software Code Quality series within our Series Library

References

1. Hopper (1978) p. 16.

2. https://www.iec.ch/functionalsafety/standards/page2.htm

3. https://standards.globalspec.com/std/14256883/EN%2050128
4. https://www.iso.org/standard/43464.html

5. https://wiki.sei.cmu.edu/confluence/display/seccode/Top+10+Secure+Coding+Practices?focusedCommentId=88044413

6. Google Map view

About the Author

Rafael Taubinger | Technical Marketing Specialist, IAR Systems

Rafael Taubinger is the Technical Marketing Specialist at IAR Systems, based at the headquarters in Sweden. Prior to his current role, he served as Global FAE Manager and Senior FAE at IAR Systems. He has over 15 years of experience in the embedded industry and holds a B.S. degree in Electrical Engineering with emphasis in Electronics and a Master of Business Administration (M.B.A) degree in Business Management.

Rafael is highly skilled in C/C++ programming languages for 8-, 16- and 32-bit microcontrollers, and has 2000+ hours of technical training in the U.S., Latin America, and Europe about embedded applications, C/C++ programming, safety coding, system reliability, efficiency, modeling, code analysis, and best development practices.

Sponsored Recommendations

Comments

To join the conversation, and become an exclusive member of Electronic Design, create an account today!