Focus on and star our public account for direct access to exciting content
Source | Online Materials
In a standard embedded project, software defects must be considered from the design stage.So, what aspects do you usually consider regarding design flaws in embedded software?
Overview
In high-quality and high-safety products, software plays an increasingly significant role. From the requirements analysis phase to software development, all levels of testing must strive to avoid software issues.On one hand, defects should be avoided through design; on the other hand, software products should undergo thorough testing to detect hidden defects as early as possible, preventing serious consequences and losses after mass production.Software testing is one of the effective methods for discovering software defects. Embedded software testing is categorized into static testing and dynamic testing based on whether the system under test is executed:
- Static testing does not require compiling and executing the source program. It analyzes the source code for lexical syntax, programming standards, data flow, control flow, metrics, etc., to obtain the structure and characteristics of the program. Formal methods are used to verify and prove whether the program complies with safety rules, allowing for a comprehensive understanding of the program’s features.
- Dynamic testing requires analyzing the software defects by obtaining dynamic information from the program, such as analyzing the program’s memory state, coverage, and execution results, which is more conducive to understanding the dynamic behavior characteristics of the program.
Many code defects arise during program execution, exhibiting concealment and unpredictability, such as array out-of-bounds, dynamic memory allocation, memory overflow, illegal pointer references, and implicit conversions with type inconsistencies. These errors cannot be detected by the compiler during the compilation phase.In large-scale, highly complex software, relying entirely on manual inspection may lead to issues being overlooked due to subjective reasons.Embedding a library of common defect patterns into tools for automated detection of code defects can significantly enhance testing efficiency, prevent recurring issues, and reduce the workload of testers.
Classification of Defect Pattern Rules
Rule ClassificationClassification by Error TypeTo further study the mechanisms and distribution of software errors, the rules in the typical defect pattern library for C language are classified according to the type of rule check.(1) Numerical Checks: Division by zero, array out-of-bounds.(2) Pointer Usage Checks: Null pointer dereference.(3) Data Flow Checks: Variables defined but not used before being reassigned.(4) Control Flow Checks: Missing else branch at the end of if-elseif statements.(5) Initialization Checks: Using uninitialized variables before assignment.(6) Type Conversion Checks: Implicit type conversions introduced by inconsistent data types.(7) Improper Operator Usage Checks: Control expressions in relational expressions, logical expressions, and conditional statements should not be assignment expressions “=”, and using consecutive comparison operations may lead to code execution logic differing from expectations.Classification by SeverityBased on the severity of errors that may arise from faults, affecting the software or system, each rule is assigned a priority of high, medium, or low.(1) Critical: Division by zero; array out-of-bounds; null pointer dereference.(2) Moderate: Using uninitialized variables before assignment; implicit type conversions due to inconsistent data types; control expressions in relational expressions, logical expressions, and conditional statements should not be assignment expressions “=”; using consecutive comparison operations may lead to code execution logic differing from expectations.(3) Minor: Missing else branch at the end of if-elseif statements; variables defined but reassigned without being used.Rule AnalysisNumerical ChecksErrors occurring during continuous execution are termed runtime errors. Once such an error occurs in the program, it can lead to actual results differing from expected results, potentially even causing a computer reset.Numerical checks, as an important aspect of runtime error checks, may occur under specific runtime conditions. Even programs that have undergone rigorous testing may still have unexpected shallow paths that lead to software safety issues.(1) Array Out-of-BoundsAccessing an element in an array using its index is called array access. If an array is defined with n elements, occupying a contiguous block of memory, accessing the n elements (indices 0 to n-1) is legal. However, accessing elements beyond this range (such as index n) accesses other variables, which is illegal and termed “out-of-bounds.”Array out-of-bounds behavior at runtime is unpredictable; it may not cause severe consequences, or it may lead to program crashes. Therefore, checks must be performed to ensure that array access does not go out of bounds to guarantee program correctness. See Table 1 for code examples.Table 1 Code Example of Array Out-of-Bounds
(2) Division by ZeroPerforming a division by zero operation can lead to a calculation result of an extremely large value, exceeding the maximum range that the data type can represent, resulting in overflow. The computer program’s protective handling of overflow may involve resetting the computer.Therefore, when integers and floating-point numbers are used as denominators in code, protection should be implemented to prevent exceptions caused by division by zero. See Table 2 for code examples.Table 2 Code Example of Division by Zero
Null Pointer DereferenceNull pointer dereference is a common dynamic memory error. Pointer variables can point to heap addresses, static variables, and null address units. When a reference points to a null address unit, it results in a null pointer dereference fault, leading to unpredictable errors, system crashes, or abnormal resets. Therefore, before dereferencing a pointer, it should first be checked for NULL; if it is NULL, dereferencing should not occur. See Table 3 for code examples.Table 3 Code Example of Null Pointer Dereference
Variable Defined but Not Used Before ReassignmentThis rule belongs to data flow analysis rules, focusing on whether the logic of variable value operations is reasonable and correct. If it does not conform to logic, it may hide code issues. See Table 4 for code examples.Table 4 Code Example of Variable Defined but Not Used Before Reassignment
Missing Else Branch at the End of If-Elseif StatementsThis rule belongs to control flow analysis rules, focusing on the structure of the program.It is necessary to extract control flow information from the code analysis, as the control flow of the program determines which specific values assigned to variables may propagate to which parts of the program.If there exists a path where the variable value is inconsistent with expectations, it may hide code issues. See Table 5 for code examples.Table 5 Code Example of Missing Else Branch at the End of If-Elseif Statements
Using Uninitialized VariablesDuring program execution, variables reside in memory, which is divided into three parts for user storage: program area, static storage area, and dynamic storage area.Global variables are stored entirely in the static storage area; the dynamic storage area mainly holds: function parameters, automatic variables (local variables without static), function call context protection, and return values.If dynamic storage area variables are used before being assigned initial values, due to uncertain variable values, unpredictable errors may occur. See Table 6 for code examples.Table 6 Code Example of Using Uninitialized Variables
Implicit Type Conversions Due to Inconsistent Data TypesWhen the types of the assigned variable and the variable being assigned differ, relevant checks for data type conversion are required.Generally, data type conversions are automatically performed by the compiler without manual intervention, known as implicit type conversion.However, if the program requires a specific type of data to be converted to another type, explicit type conversion operators can be used, which is termed explicit conversion.
Figure 1 Compiler Automatic Promotion RulesThe C language compiler’s data type promotion rules can be summarized as promoting from smaller data types to larger data types, termed upward conversion; conversely, it is termed downward conversion. The compiler’s automatic conversion rules are shown in Figure 1.If upward implicit type conversion occurs, when two data types are added, if the significant digits of the smaller data type exceed the effective data bits of the larger data type, it may lead to precision loss in the calculation result.If downward implicit type conversion occurs, if the data value of a large-range variable exceeds the effective range that a small-range variable can represent, the compiler will truncate and discard high-order data after conversion based on the representation of the data value in memory, resulting in incorrect conversion results. Therefore, the compiler does not allow implicit downward conversion; if it must be done, explicit methods must be used. However, explicit methods may also have issues, such as rounding up or down in the calculation result of two data types added together.For example, converting a high-precision double type variable to a float type variable requires explicit type conversion. The conversion from double to float is a downward conversion, which the C language compiler cannot automatically perform, thus requiring explicit type conversion of the double type variable to the float type variable. See Table 7 for code examples.Table 7 Code Example of Type Conversion
Improper Operator Usage(1) Control expressions in relational expressions, logical expressions, and conditional statements should not be assignment expressions “=”.Using an assignment operator in the above expressions will cause the condition check to always evaluate to true, leading to code execution logic differing from expectations. See Table 8 for code examples.Table 8 Code Example of Prohibited Assignment Expressions in Certain Expressions
(2) Using consecutive comparison operations may lead to code execution logic differing from expectations.For example, a consecutive comparison operation like: 1<a<5 will always evaluate to true regardless of the value of variable a. See Table 9 for code examples.Table 9 Code Example of Using Consecutive Comparison Operations
Code Sampling and Result Analysis
Using code sampling methods to verify and analyze the defect pattern library rules checked by the static analysis tool SpecChecker, which has functions for checking programming standards, fault defect analysis, and shared data variable analysis.Using the fault defect analysis function of this tool to check randomly sampled code, providing tool analysis results, suggestions for the tool and rules, and clarifying considerations during code design.Sampling Code Conditions and MetricsSampling 200,000 lines of embedded C code, with processor types including C51, GCC, DSP, selecting the following metrics as measures for the tool, focusing on the problems discovered by the tool.(1) Tool Alerts: Total number of alerts for rule violations by the tool;(2) Confirmed Issues: Locations of rule violations alerted by the tool, confirmed by manual inspection to indeed have program issues;(3) Tool False Positives: Locations of rule violations alerted by the tool, confirmed by manual inspection to not have any violations or errors;(4) Tool Missed Alerts: Code violating rule requirements that the tool did not alert.Tool Analysis ResultsTable 10 Defect Pattern Check Results
SuggestionsBased on the results in Table 10, improvement suggestions are provided from several aspects: missed rules, false positive rules, accurate location rules, alert information rules, code improvement rules, and undetected rules.(1) Missed Rules: The tool can effectively detect division by zero errors when the integer is 0 as the denominator, with high accuracy, but it failed to detect cases where the denominator is a floating-point 0.0. During the requirements analysis and code design phases, consideration should be given to whether the denominator may be zero; if so, division by zero protection should be implemented.(2) False Positive Rules: The tool has a certain degree of false positives for the rule “variable assigned but not used before reassignment,” providing many alerts but not identifying actual program issues. It is recommended that the tool not alert for cases where local variables are defined and assigned initial values but not used before reassignment. The rule description can also further clarify under what scenarios the code logic is defective.(3) Accurate Location Rules: The tool’s checks for “array out-of-bounds,” “using uninitialized variables,” “control expressions in relational expressions, logical expressions, and conditional statements should not be assignment expressions “=”, and “using consecutive comparison operations may lead to code execution logic differing from expectations” are relatively accurate.(4) Alert Information Rules: The rule “missing else branch at the end of if-elseif statements” did not reveal substantial issues; generally, it needs to be analyzed in conjunction with the code’s processing logic to determine if problems exist.(5) Code Improvement Rules: The majority of issues arising from “converting double type data to float type” involve a certain degree of data precision loss, which may lead to calculation results having some error; it is recommended that such operations not be performed in code.(6) Undetected Rules: Currently, no occurrences of “null pointer dereference” errors have been observed. Once they occur, the consequences can be severe, potentially causing a computer reset. Developers and testers should pay attention to avoid situations where pointers are used without checking if they are null.Source from the internet, copyright belongs to the original author. If there is any infringement, please contact for removal.
‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧ END ‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧
Follow my WeChat public account, reply "planet" to join the knowledge planet, and get answers to your questions.
Click "Read the original" to view details of the knowledge planet. Feel free to share, bookmark, like, and view.