Several readers have expressed an interest in looking at examples of defects and in understanding some of the techniques used by static analysis. Starting with this post, we plan to do a monthly series on interesting defect examples and highlight what really goes on when a checker reports a defect.
Since last week’s discussion was around the topic of how the challenges for financial services software development are not very different from other industries, today we’ll look at how the coding defects in financial services software are not very different from those in other industries.
I took a recent version of an open source package called QuickFIX, a FIX engine, and analyzed it with Coverity Static Analysis®. FIX, the Financial Information eXchange (FIX) protocol, is a language that defines specific kinds of electronic messages for communicating securities transactions between two parties. You can imagine how this type of code would be commonly used in securities trading systems and financial account aggregator software.
As expected, the defects I found were memory corruptions and illegal accesses, some resource leaks and uninitialized scalars and pointers, and some string overflows – typical defects in C and C++ code. Let’s look at an example for a simple uncaught exception defect and understand what’s going on. Coverity classifies this as an error handling issue.
Here is the code snippet:
A couple of useful static analysis techniques are in play here:
1. Dataflow analysis
One of the first things the analysis does is build a control flow graph from the source code. This allows analysis to test and look for defects on all execution paths without the need for test cases. For our example, the analysis would build a control flow graph for the ‘switch’ statement (the case condition is a part of a switch block), include all the possible case conditions, follow the ‘break’ statements for each ‘case’, and evaluate if the thrown exception is caught. If it is not, it will report a defect.
2. Interprocedural analysis
Another important technique for accurate and deep static analysis is traversing the function calls and finding defects across function and method boundaries. In this example, function SessionSettings() is called that could potentially throw a “FIX::ConfigError” exception. How does the analysis engine know that? It analyzed the function called, noticed the possible thrown exception, and using dataflow analysis figured out that it was not being caught. And that’s the defect – probably a minor one, but might be severe if you rely on exception handling for managing error conditions.
Obviously a lot more goes on to ensure that the results of static analysis are accurate, real and fast. But this simple example shows a couple of basic techniques.