Using static analysis to diagnose & prevent failures in safety-critical device designs
By David N. Kleidermacher
Barriers To Widespread Adoption
A recent survey found that less than 5% of device software engineers
make regular use of static analysis tools [7]. Engineers cited the following
main technical barriers to adoption: poor integrated
development environment (IDE) integration and prohibitive
execution time.
IDE Integration. Commercial
static analyzers often run as separate tools, distinct from the tool
chain used to develop and build application software. Thus, users must
separately install, license, and configure the analyzer. Configuration
can often be time consuming, requiring days of customization in order
to cajole the analyzer into processing the user's particular dialect of
source code.
An alternative approach performs static analysis within the same
compiler used to build software. This provides several advantages,
including the obvious benefit of reducing the time to effective usage.
Since static analysis is performed by the compiler, it doesn't need
to make guesses regarding the proper application of build options,
location of include header files and directories, or the definitions of
preprocessor macros. In fact, software projects are often built by
development teams in multiple configurations. By running within the
compiler, the analyzer sees each distinct configuration in its precise
deployed form.
Flaws discovered by the static analyzer can be interleaved with the
other standard diagnostics output by the compiler (Figure 5 below). Furthermore, common
IDE integrations between the project builder and the editor augment the
usability of the static analysis tool: when a static analysis flaw is
reported during the build process, the user can hyperlink from the
builder's output window back to the source code quickly, rectify the
error, and then return to building the program.
 |
| Figure
5 - Integration of static analysis with project builder |
With proper project management integration, static analysis becomes
merely another option that any developer can easily enable or disable
from an options menu.
Execution Time.
Many commercial static analyzers require orders of magnitude more
execution time than a regular compile. Large software projects may
require hours, days, even weeks of analysis time. This execution cost
presents a barrier to adoption, causing static analysis, if used at
all, to be employed only periodically or during test phases.
Static analysis tools could enjoy improved adoption if execution
time can be reduced to a level that encourages constant use; developers
can detect flaws while software is first written and before it is ever
committed to a configuration management system.
Here again is where the integrated compiler approach proves
beneficial. The static analysis engine can take advantage of compiler
dataflow analysis, constant propagation, and path pruning algorithms,
developed and tuned over many years for execution time efficiency of
complex code optimizations, to improve run-time performance.
Secondly, the total time to build and analyze software would be
reduced since the compiler uses a single parsing pass of the code to
perform both compilation and analysis.
Integration with the compiler may also enable the analyzer to take
advantage of the IDE's existing distributed build mechanism. As a
result, the parsing pass for the project's source code can be
distributed across idle workstation assets on a user's network,
dramatically reducing the total analysis time.
Static analyzers could also be integrated with the IDE's project
management system. The project manager typically uses dependency
analysis to monitor which code subroutines have changed since the most
recent build. In much the same way, static analysis can be limited to
the program subgraph affected by the last modification. This
optimization dramatically reduces analysis time when used throughout
the software development cycle.
Studies have shown that an application of static analysis that takes
advantage of compiler integration, change dependency analysis, and IDE
distributed processing yields analysis times comparable with
traditional compilation times, thereby removing an important barrier to
adoption.