more real-world static analysis results

Matthias Lang matthias@REDACTED
Sun Oct 24 13:45:35 CEST 2004


inspired by Tobias' excellent presentation (best of the conference,
IMO) at the EUC, I ran a couple of static analysis tools on a subset
of Corelatus' production code. This code has an extensive test-suite
and much of it has been in production use for years.

Presenting the results in the same format as the paper, as run on
about 20kloc of code

  Tool     |  Explosives    Camouflages    Cemeteries    Spurious
 Dialyzer  |  2             1              3             2
 xref      |  1             0              3             0

The 'Dialyzer' paper observes that the bugs found by static analysis
in general, and dialyzer in particular, tend to be shallow. The bugs
found above are indeed all simple bugs---easy to fix and not causing
any real trouble.

Breaking the bugs down:

True bugs (code shown is simplified for clarity)

 1.  String = "string" ++ 5 + (integer_to_list(N - 5) div 2) ++ "A".  

 2.  case is_ip4_addr(Addr) of              %% returns {ok, Tuple} | error
       {ok, _} -> E#eth_params{gw = Addr};
       {error, Reason} -> {error, Reason}

 3.  Call to a module which doesn't exist (typo in module name)

 The first two were found by dialyzer, the last by xref. 

 These bugs were missed by our test suite because the offending lines 
 of code were not exercised (covered) by any test.

 These bugs were "missed" by live operation for various reasons. 
 #1 only happens in a hardware configuration which isn't currently used.
 #2 only happens if an external system does the wrong thing first.
 #3 only happens in a feature which isn't currently used.
 Dialyzer also found this code:

     Bin = list_to_binary([1|<<2>>])

 The list is improper, but it doesn't matter because list_to_binary/1
 works as expected on that type of improper list, which is also why
 it passes the test suite.


  The remaining eight problems found by dialyzer and xref were
  non-bugs. In all cases the warnings can be eliminated by changing
  the code slightly, e.g. I have to stop using this idiom to mark

     die = nyi,   % nyi = not-yet-implemented

I'm currently playing around trying to get 'cover' to work on my
target system. It's not entirely trivial because it requires a fairly
complete erlang environment and is relatively memory hungry.


More information about the erlang-questions mailing list