17 Noncovered Code (Dead, Extraneous, and Deactivated Code)

Acronym

PSAC Plan Software Aspects of Certification
SAS Software Accomplishment Summary

17.1 Introduction

When structural coverage is performed to ensure that the requirements-based tests fully exercise the code structure (as discussed in Chapter 9), there may be some code that is not covered (i.e., not exercised by the tests). If the lack of coverage is due to missing requirements or tests, the requirements and tests are updated and re-executed as appropriate. There may be some code that cannot be exercised in the test environment but still meets the requirements (e.g., code that functions during initialization or defensive code). Such code needs to be verified through an alternate approach, such as analysis or code inspection. However, even after this, there may still be some noncovered code that is classified as extraneous, dead, or deactivated. This chapter discusses these classes of code and provides recommendations for how to handle them.

17.2 Extraneous and Dead Code

The term extraneous code was added in the update from DO-178B to DO-178C. There was considerable debate about what to call this class of code that is (1) not exercised during requirements-based testing and (2) not traceable to the functional requirements. Several alternate terms were considered, such as untraceable code, unreached code, and noncovered code. The term extraneous code won the contest.

DO-178C defines extraneous code as: “Code (or data) that is not traceable to any system or software requirement. An example of extraneous code is legacy code that was incorrectly retained although its requirements and test cases were removed. Another example of extraneous code is dead code” [1].

The definition of extraneous code identifies dead code as a subset of extraneous code. DO-178C explains that dead code is “executable object code (or data) which exists as a result of a software development error but cannot be executed (code) or used (data) in any operational configuration of the target computer environment. It is not traceable to a system or software requirement…” [1]. The following illustrates a simple example of dead code; as you can see, the line “calculate airspeed” cannot be reached because of the way the code is written.

if (UP and OVER) and not OUT calculate wheelspeed if OUT calculate airspeed end if end if

DO-178C requires that extraneous code (including dead code) be removed. In addition to the removal, an analysis is performed to determine (1) the effects of the code removal and (2) the need for re-verification prior to approval of the code in the airborne system [1]. This guidance has been a hard pill to swallow for many projects. However, it should be noted that DO-178C also provides some common exceptions to the rip-it-out guidance, including the following [1]:

  • Embedded identifiers in the code are not considered extraneous or dead code. Examples of embedded identifiers include checksums or part numbers.

  • Defensive programming structures to improve robustness are not considered extraneous or dead code. However, such defensive programming practices need to be clearly identified in the coding standards. Additionally, the defensive programming structure must be shown to support the implementation of the requirements and design. As an example, a commonly required defensive coding practice is to have an else for every if statement.

  • Deactivated code is not extraneous or dead code (deactivated code will be discussed later in this chapter).

  • Source or object code that does not exist in the executable object code (e.g., due to compiler or linker settings) is not considered extraneous or dead code. However, an analysis is required to show that the code does not exist in the executable object code. Additionally, procedures must be in place to ensure that such code will not be inadvertently inserted into the executable object code in the future (e.g., build procedures that explicitly state the settings and provide the reason for their existence).

When structural coverage analysis first identifies noncovered code, the data should be examined and analyzed to determine if it is a requirements problem, a test case issue, or a code issue. Don’t automatically assume that noncovered code is extraneous or dead code. In my experience, most of the initially discovered noncovered code is due to missing requirements, missing test cases, or logic errors. Once it has been determined that the noncovered code is truly extraneous or dead, then time must be spent analyzing the impact of the code and determining the best solution. Some code may appear to be dead, but when it is removed, chaos occurs. One company told me that they called some of their code zombie code because it appeared to be dead, but every now and then it came to life (not an acceptable scenario in safety-critical systems).

17.2.1 Avoiding Late Discoveries of Extraneous and Dead Code

Many developers have learned the hard way that rapid removal of dead or extraneous code late in the project’s life cycle can be problematic. Removal of dead or extraneous code after formal software testing (i.e., the testing for certification credit) has been performed must be treated with extreme caution. If code is erroneously determined to be extraneous or dead and is removed, it may be difficult to determine the impact without substantial re-verification (possibly even a re-execution of all tests). Therefore, it is important to make every effort to find coding issues as early as possible. Here are some suggestions to avoid late discoveries of dead or extraneous code:

  • Implement high-quality code reviews that specifically focus on the code’s compliance with and traceability to the requirements.

  • Keep trace data current. Each time the requirements or code change the trace data should be modified.

  • Run tests and analyze structural coverage as early as possible (as mentioned in Chapter 9, execution of tests prior to reviewing the test cases and procedures is typical). As the requirements or code changes, tests should be rerun and coverage reanalyzed. These early test runs and coverage analysis help to identify issues prior to the final test run that will be used for certification credit (i.e., the formal test run or the for-score test run).

  • Schedule time for addressing issues discovered during testing. As indicated in Chapter 9, many projects implement success-based scheduling and assume all tests will execute without issue, but this sets the project up for failure (or at least significant delays).

  • Define processes and procedures for addressing noncovered code and include examples.

17.2.2 Evaluating Extraneous or Dead Code

Even after implementing these suggestions, there may still be some extraneous code (which includes dead code) discovered late in the program. If this occurs, Figure 17.1 illustrates the steps that normally take place. Each box of the flowchart is described in the following:

Images

Figure 17.1 Steps for evaluating extraneous or dead code.

  1. Thoroughly analyze the noncovered code to confirm that it is indeed extraneous or dead.

  2. If the noncovered code is not extraneous, dead, or deactivated, make the appropriate changes to requirements or tests. If it is deactivated, ensure that it follows the guidance for deactivated code (discussed in Section 17.3).

  3. If the noncovered code is extraneous or dead, analyze the removability of the code considering the architecture. Some code is easy to remove and some is quite challenging. The feasibility determination may also need to consider the schedule. Extraneous or dead code found late in the program may have schedule constraints, as well as technical constraints.

  4. Evaluate the effects of activating the extraneous or dead code if it is not removed. Consider what would happen if the extraneous or dead code was inadvertently activated (evaluate safety and functional effects).

  5. If the analysis ensures with a high level of confidence that inadvertent activation of the extraneous or dead code is benign from a safety perspective (e.g., unused variables), it may be possible to obtain a special agreement from the certification authority. This agreement typically requires the removal of the code during the first postcertification modification. This approach is subjective and must be thoroughly analyzed and justified, and presented to the certification authority as soon as possible. The criticality of the software and the nature of the extraneous or dead code will affect the details of the proposed strategy.

  6. Seek certification authority’s agreement on the proposed strategy as soon as possible.

  7. Remove the extraneous or dead code and perform re-verification, including rerun of the appropriate tests, if one of the following is true: (1) removal is feasible (from a technical and schedule perspective), (2) the effects of activation are not benign (i.e., safety could be impacted), or (3) the certification authority does not agree to approve the software with the extraneous or dead code remaining.

  8. If the certification authority agrees to allow the extraneous or dead code in for the initial approval, document the terms of the agreement and identify the specific problem report(s) that addresses the extraneous or dead code in the Software Accomplishment Summary (SAS).

  9. If an agreement is reached, ensure that steps are in place to honor the agreement (i.e., the schedule for removal is implemented). The team that modifies the software (normally not the same team that developed the software) must be made aware of the agreement when they begin the software upgrade, so they can ensure the changes are tracked, implemented, and verified.

It should be noted that extraneous or dead code discussions and evaluations normally occur at the source code level because most projects perform their structural coverage measurement on the source code. However, some companies perform structural coverage on the object or machine code. If this is the case, the same issues regarding extraneous or dead code still need to be addressed—the code just looks different.

As noted in Chapter 9, for level A software there is an additional objective required when performing structural coverage on the source code. The source to object code traceability is analyzed to ensure that the compiler did not generate extraneous or dead code. For level A software, any extraneous or dead code generated by the compiler must be analyzed and addressed as described earlier.

17.3 Deactivated Code

Deactivated code is often used to create flexible yet fully compliant soft ware. Deactivated code is related to extraneous or dead code because it may show up as noncovered code during structural coverage analysis. However, unlike extraneous or dead code, deactivated code is planned and implemented by design.

The DO-178C glossary defines deactivated code as follows:

Executable Object Code (or data) that is traceable to a requirement and, by design, is either (a) not intended to be executed (code) or used (data), for example, a part of a previously developed software component such as unused legacy code, unused library functions, or future growth code; or (b) is only executed (code) or used (data) in certain configurations of the target computer environment, for example, code that is enabled by a hardware pin selection or software programmed options. The following examples are often mistakenly categorized as deactivated code but should be identified as required for implementation of the design/ requirements: defensive programming structures inserted for robustness, including compiler-inserted object code for range and array index checks, error or exception handling routines, bounds and reasonableness checking, queuing controls, and time stamps [1].

Some examples of deactivated code usage include the following:

  • Debug code used during testing or troubleshooting in the lab. The debug code is deactivated when installed in the aircraft.

  • Maintenance features used on the ground by an authorized technician. The maintenance features are deactivated during aircraft operation.

  • Option-selectable software, which is used instead of hardware pins to select a preapproved software configuration based on the specific operator’s needs. The software not selected is deactivated.

  • A subset of an operating system that was developed to satisfy DO-178C objectives and to meet the needs of multiple users. The features not used are deactivated.

  • A flight management system designed to take input from multiple sensors that can be selected depending on the aircraft configuration. The sensor code not used is deactivated.

  • An engine controller developed for one-engine or two-engine configuration. Either the one-engine or two-engine code is deactivated.

  • Selected functions from a library designed to meet the needs of multiple software teams. The unused library functions are deactivated.

  • Compiler options (e.g., #ifdef) added to use the same code in multiple places (e.g., same code for multiple lanes or for multiple platforms). During compilation, such code is removed from the executable object code; hence, it is deactivated.

The list goes on and on. Deactivated code allows configurability of the software to meet the needs of multiple users. As you can see from the definition of deactivated code and the examples, deactivated code falls into two basic categories: (1) code that will never be used in flight, and (2) code that may be used at some time, depending on the configuration of the system. Table 17.1 summarizes the two categories and some things to consider for each category.

I once encountered a company that tried to classify their dead code as deactivated code at the end of the project. However, there’s a big difference between the two: deactivated code is planned and designed; dead code is not.

Table 17.1 Overview of Deactivated Code Categories

Category Description Considerations
Category one

Code that will NEVER be activated during aircraft operations.

For example, debug code.

  • The deactivated code must be disabled during aircraft operation.

  • The functionality of the deactivation mechanism must be proven to work (it needs requirements and tests).

  • The deactivation approach must support the software level of the activated software.

  • The deactivated code itself is generally treated like level E software from a certification perspective. However, it is still recommended that there be requirements and some level of testing on the deactivated code, in order to ensure it meets its intent.

Category two Code that may be used in some configurations but not others.
  • The deactivated code must be tied to requirements like all other airborne software.

  • The deactivated code must be assured to the appropriate software level since it is intended to be used in the future. That is, the deactivated software must meet the applicable DO-178C objectives for the software level.

  • The deactivation approach to ensure proper deactivation and configuration must be included in the requirements and design.

  • The deactivation approach must meet the appropriate development assurance level and will need to be tested.

Figure 17.2 summarizes the processes to consider for deactivated code, as well as references to the related DO-178C sections. The planning, development, and verification processes are described in the following subsections.

Images

Figure 17.2 Summary of deactivated code process.

17.3.1 Planning

One of the primary differences between extraneous or dead code and deactivated code is that deactivated code is planned. I’ve never seen anyone plan to add dead code (they plan to deal with it if it arises, but they don’t plan to implement it). Deactivated code should be explained in the Plan Software Aspects of Certification (PSAC), as well as in the Software Development Plan and Software Verification Plan. The deactivated code plan is normally included as an additional consideration in the PSAC. The PSAC should explain the types of deactivated code planned, the category of the deactivated code (category one or category two), the deactivation mechanism(s), and the development and verification approach for the deactivated code and the deactivation means. The Software Development Plan explains more details on the development approach for the deactivated code. It is important to give the developers direction on how to handle the deactivated code during requirements, design, and coding phases. The Software Verification Plan provides details on the verification approach for both the deactivated code itself (particularly for category two code) and for the deactivation mechanism(s).

17.3.2 Development

As the DO-178C definition of deactivated code implies, deactivated code is driven by the requirements and is documented in the design. DO-178C section 5.2.4 provides guidance (called activities) for designing deactivated code [1].

First, the deactivation mechanism needs to be designed and implemented so that the deactivated code has no adverse impact on the active code. There are a variety of ways to deactivate the code. Regardless of the mechanism used to deactivate the code, it must be considered in the safety assessment process and it must be verified to effectively deactivate the desired code. Some examples of deactivation mechanisms include the following:

  • Using an aircraft personality module to select the appropriate configuration for that aircraft. The module may be a physical module with switches or it may be a configuration file.

  • Selecting pins to identify the configuration. If this is the approach, it is recommended that two or more pins are used, since one pin can easily short or open. Likewise, multiple signals are generally used (e.g., weight-on-wheels alone could be misinterpreted). The possible failures should be considered by the safety team.

  • Using a smart compiler which does not compile library functions that are not included in the code (hence removing the deactivated code from the executable image).

  • Using a compiler option (such as #ifdef) to remove the code from the executable image.

Second, there must be evidence that the deactivated code is not active in the environments where it is not intended to be used or where it is not approved. This requires effective configuration control of the deactivated code and its use. The configuration control must be considered at the software level, as well as at the aircraft and system level. For example, if using a library of functions during the development, there must be a process to ensure that only approved library functions are used. If care isn’t taken, future developers may just assume that the entire library is approved. One way to handle this is to only release the approved functions, so the unapproved functions are unavailable.

Third, the deactivated code itself needs to comply with applicable DO-178C objectives. The applicable objectives depend on the category of the code. For category one deactivated code, level E is usually acceptable because this software will not be used during flight operations. However, if the deactivated code will be used to make important maintenance decisions or to perform vital maintenance activities, it may need to be developed to a higher level. Category two deactivated code should to be treated like active code during development, since it is intended to be used in some configurations.

17.3.3 Verification

Both the deactivated code and the deactivation mechanism need to be verified to the appropriate DO-178C software level. If the compiler is not a qualified tool and smart compiling or compiler options were chosen as the deactivation mechanism, it is important to analyze the compiler output to ensure that the deactivated code truly is removed from the executable image.

This brings me to a somewhat common and controversial issue related to deactivated code. Sometimes, it can be challenging to classify the deactivated code as category one or category two. The project goal may be to have category two deactivated code in order to satisfy the needs of multiple customers. However, the actual implementation may end up different (due to schedule or changes in project direction). This may lead to some category two code being downgraded to category one. This must be carefully evaluated and discussed with the certification authority. If this approach is taken, there needs to be concrete limitations to prevent users and future developers from thinking that the deactivated code is approved for future use.

References

1. RTCA DO-178C, Software Considerations in Airborne Systems and Equipment Certification (Washington, DC: RTCA, Inc., December 2011).

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.176.194