A recent software bug caused a serious data damage in our customer’s side, which is using an uninit sturcture member. This post gives a practical comparison between kinds of static code analysis tools for this specific bug among popular commerical tools and open source tools. This post does NOT try to tell which tool is better but only for information. On the other hand, this ‘stupid’ bug may be a good start to begin with real static code analysis…
/* daveti_uninit1.c - BUG */ typedef struct s { int a; int b; }S; int test(S *y) { y->b=0; return 0; /* member a has never been used or init'd */ } int main() { int w=0; S x; int ret; ret=test(&x); /* pass the address of structure x to function test */ w=x.a; /* now use the uninit structure member a */ return 0; } /* daveti_uninit2.c - BUG */ typedef struct s { int a; int b; }S; int test(S *y, int k) { if (k==0) { y->b=0; y->a=0; /* y.a is only init'd when k is 0 */ return 0; } if (k==1) { y->b=0; return 0; /* y.a has never been used or init'd */ } return 0; } int main() { int w=0; S x; int ret; ret=test(&x, 1); /* pass the address of structure x to function test */ w=x.a; /* use the uninit structure member a */ return 0; } /* daveti_uninit3.c - GOOD */ typedef struct s { int a; int b; }S; int test(S *y, int k) { if (k==0) { y->b=0; y->a=0; return 0; } else { y->b=0; y->a=1; return 0; } } int main() { int w=0; S x; int ret; ret=test(&x, 1); /* pass the address of structure x to function test */ w=x.a; return 0; }
Tools / daveti_uninitX.c | daveti_uninit1.c (bug) | daveti_uninit2.c (bug) | daveti_uninit3.c (good) |
gcc –Wall (4.1.2) | No | No | No |
Klocwork Insight 9.2 | Yes | No | N/A |
Coverity 5.5.1 | Yes | Yes | No |
CppCheck 1.47 | No | No | No |
Splint 3.1.1 | Warning when passing x to func | Warning when passing x to func | Warning when passing x to func |
Uno 2.13 | No | No | No |
For this speical case, well, Coverity explains the reason why it is the top 1 in static code analysis in commercial products. However, as the bug has been reported to Klocwork, it should have no problem in future release. Meanwhile, as gcc is a pure compiler which apparently does not focus on code analysis, it may not be a surprise to get such a result; CppCheck/Splint/Uno, on the other hand, show nothing to help because of internal limitation. Another 2 open source tools maybe worth a try are mygcc and saturn. If you have any thoughts, please leave me a commemt:)