Researchers at the FDA's Office of Science and Engineering Laboratories investigating new techniques for analyzing software in medical devices are using static analysis tools to uncover potential flaws in a device under review.
Case Study: Post-market static analysis
At OSEL, we used static analysis for the post-market review of a commercial medical device. The aim of this analysis was to determine all possible potential causes for failure in the software and to assess compliance to established software and quality control standards. GrammaTech's CodeSonar static analysis tool was employed to carry out the analysis. CodeSonar is a source-code analysis tool that performs a whole-program, interprocedural analysis on C/C++ code to identify complex programming bugs that can result in system crashes, memory corruption, and other serious problems.
The software for the device under review was implemented largely in C/C++, with some macros defined using low-level assembly code. The software was deployed in the form of three independent modules, comprising approximately 200,000 lines of code.
As the compiler used by the manufacturer was nonstandard, a mock environment was created based on the documentation accompanying the source code. The result of this was a makefile that could be used to emulate the original compilation environment. In addition, several configuration parameters were changed from the default in order to improve the precision of the analysis. This included increasing the number of paths being searched in each procedure, maximizing the path finding effort, and setting the lower bound for the null pointer threshold to 1 to indicate that all address values (except NULL) could be dereferenced safely.
Finally, the tool was run for each of the three modules separately. The output of the analysis was generated as a navigable HTML report, with links to specific regions in the source code that contained the errors.
Figure 1 shows part of the output generated by the static analysis tool. The code in the figure is an "Uninitialized variable" warning. This warning is generated to report the attempted use of a variable that has not been initialized (names of the variables in the code have been deliberately changed to protect the manufacturer's confidentiality).
View the full-size image
The code shown in the figure depicts part of a procedure S_Keys that has a number of variables defined locally. Of these, the variables is_button_pressed, number, and button_press are initialized to default values at the start of the procedure. However, the variable button is not initialized. Instead, it is expected to be assigned a value by the function ProcessButton, to which it is passed as a parameter, invoked at line 1267.
Moreover, the function ProcessButton is invoked from within a conditional loop and may itself contain conditional statements that would not always guarantee a valid value being assigned to the variable button. Thus, when used in the switch statement on line 1272, button is flagged as an "Uninitialized variable." This could lead to an unintended path being executed along the switch statement, which may ultimately lead to device malfunction.
In all, static analysis of the code produced a total of 736 such warnings. A breakdown of these warnings classified by the different warning classes is listed in Table 1.
View the full-size image