Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
C    Ruby 1.9 trunk          @ikegami_ _
@ikegami_ _•   2003•   2003-2010    •              Haskell    •   C        •   10/27 - 11/10    2•   Ruby/Mathematica, Rub...
1/2•                       C++    •   BLAST    •   Frama-C        •            •            •            •     CIL        ...
2/2•                     ←•    • cppcheck         C C++     • Emacs + Flymake     • Vim +       • Vim + QuickFix + errorma...
Emacs + Flymake + cppcheck                    →
•    • cppcheck    • splint•    • BLAST    • Frama-C
•               -Wall•    •        •            ••
•   division by zero   •   assert•             unroll                       •                           assertion•   if•••...
cppcheck•      written in C++• C/C++  •  • Tokenize  • Run all checks - pattern matching of the tokens           http://so...
cppcheck                 ruby•   ruby-1.9 trunk revision 33685 (2011-11-09   )    •   compile.c      77 files   2:01:02.55 ...
cppcheck                       Ruby                   6[hash.c:2351]: (error) Memory leak: str[io.c:5264]: (error) fflush()...
hash.c           [hash.c:2351]: (error) Memory leak: str2351 } /*              ruby_setenv         */2303             str ...
io.c   [io.c:5264]: (error) fflush() called on input stream   "stdin" may result in undefined behaviour5264        fflush(std...
splint•                        written in C••                              annotation•   cppcheck•    •   cont.c gc.c rand...
splint hash.c•   ruby-1.9 trunk revision 33685 (2011-11-09   )•   397•   header    •   Solaris        Solaris       configu...
splint regcomp.c•   ruby-1.9 trunk revision 33685 (2011-11-09   )•   737    •        •
splint regcomp.cregcomp.c:180:10: Only storage uslist->us->target(type struct _Node *) derived from released storage is no...
176   static void177   unset_addr_list_end(UnsetAddrList* uslist)178   {179     if (IS_NOT_NULL(uslist->us))180       xfre...
183   static int184   unset_addr_list_add(UnsetAddrList* uslist, int offset, struct _Node* node)185   {186     UnsetAddr* ...
false positive
BLAST • with CIL                 OCaml •   •            assert()   •   • asserthttp://mtc.epfl.ch/software-tools/blast/inde...
escape
#include <assert.h>int watched; /* a global variable */void foo(int i) { watched = i; }     ←void bar(){  int j;  foo(j); ...
#include <assert.h>int *watched;void foo(int *p) { watched = p; }void bar(){  int i, *j;  i = 1;  j = &i;  foo(j);  assert...
ruby 1.9 trunk• for   while• if  ••  •  •
Frama-C• with CIL               OCaml•C • •   • value plug-in   ←   • users plug-in                          http://frama-...
division by zerovoid foo(int x, int y){  int z = x / y; /* y should not be zero */  return;}int main(int argc, char **argv...
Frama-C value plug-in% frama-c -val foo.c[value] Analyzing a complete application starting at mainfoo.c:3:[kernel] warning...
division by zero • ruby trunk revision no. 33685  • bignum.c    • 1044 ds[k] = (BDIGIT)(num / hbase);  • util.c    •      ...
Frama-C users plug-in•       callee    •
void foo(void) {}void bar(void) {foo();}int main(void){  bar();  return 0;}          % frama-c -users foo.c          [kern...
ruby            string.ccalleehttp://sovmoess.tumblr.com/post/12364993205/frama-c-ruby-1-9-string-c-callee                ...
•    •   false positive    •    •                                 CPU•          annotation    •                    annotat...
•2          C  • ruby-1.9 trunk revision 33685•      cppcheck/splint  • escape• BLAST/Frama-C  •
C言語静的解析ツールと Ruby 1.9 trunk
Upcoming SlideShare
Loading in …5
×

C言語静的解析ツールと Ruby 1.9 trunk

4,246 views

Published on

Ruby 1.9 trunk のソースコードに、既存の静的解析ツール(cppcheck, splint, BLAST, Frama-C)を適用した/適用しようと試みた実験の紹介です。

Published in: Technology, Education
  • Be the first to comment

C言語静的解析ツールと Ruby 1.9 trunk

  1. 1. C Ruby 1.9 trunk @ikegami_ _
  2. 2. @ikegami_ _• 2003• 2003-2010 • Haskell • C • 10/27 - 11/10 2• Ruby/Mathematica, Ruby/Ming, RushCheck, Karatsuba
  3. 3. 1/2• C++ • BLAST • Frama-C • • • • CIL GCC
  4. 4. 2/2• ←• • cppcheck C C++ • Emacs + Flymake • Vim + • Vim + QuickFix + errormaker
  5. 5. Emacs + Flymake + cppcheck →
  6. 6. • • cppcheck • splint• • BLAST • Frama-C
  7. 7. • -Wall• • • ••
  8. 8. • division by zero • assert• unroll • assertion• if••• Call flow graph•
  9. 9. cppcheck• written in C++• C/C++ • • Tokenize • Run all checks - pattern matching of the tokens http://sourceforge.net/apps/trac/cppcheck/
  10. 10. cppcheck ruby• ruby-1.9 trunk revision 33685 (2011-11-09 ) • compile.c 77 files 2:01:02.55 • error 6 • compile.c 54:46.94s•
  11. 11. cppcheck Ruby 6[hash.c:2351]: (error) Memory leak: str[io.c:5264]: (error) fflush() called on input stream "stdin" mayresult in undefined behaviour[regcomp.c:5524]: (error) Memory leak: new_reg[vm_dump.c:831]: (error) Possible null pointer dereference: vm -otherwise it is redundant to check if vm is null at line 778[vm_dump.c:834]: (error) Possible null pointer dereference: vm -otherwise it is redundant to check if vm is null at line 778[vm_dump.c:835]: (error) Possible null pointer dereference: vm -otherwise it is redundant to check if vm is null at line 778
  12. 12. hash.c [hash.c:2351]: (error) Memory leak: str2351 } /* ruby_setenv */2303 str = malloc(len += strlen(value) + 2); str free 2287 #elif defined __sun Solaris
  13. 13. io.c [io.c:5264]: (error) fflush() called on input stream "stdin" may result in undefined behaviour5264 fflush(stdin); /* is it really needed? */Q. How can I flush pending input so that a userstypeahead isnt read at the next prompt? Willfflush(stdin) work?A. fflush is defined only for output streams. (omit) comp.lang.c FAQ list · Question 12.26a
  14. 14. splint• written in C•• annotation• cppcheck• • cont.c gc.c random.c thread_pthread.h http://www.splint.org/
  15. 15. splint hash.c• ruby-1.9 trunk revision 33685 (2011-11-09 )• 397• header • Solaris Solaris configure • cppcheck hash.c x86
  16. 16. splint regcomp.c• ruby-1.9 trunk revision 33685 (2011-11-09 )• 737 • •
  17. 17. splint regcomp.cregcomp.c:180:10: Only storage uslist->us->target(type struct _Node *) derived from released storage is notreleased (memory leak): uslist->us(omit) 176 static void 177 unset_addr_list_end(UnsetAddrList* uslist) 178 { 179 if (IS_NOT_NULL(uslist->us)) 180 xfree(uslist->us); 181 }
  18. 18. 176 static void177 unset_addr_list_end(UnsetAddrList* uslist)178 {179 if (IS_NOT_NULL(uslist->us))180 xfree(uslist->us); typedef struct {181 } int offset; struct _Node* target; } UnsetAddr; uslist->us->target typedef struct { free int num; int alloc; UnsetAddr* us; } UnsetAddrList;
  19. 19. 183 static int184 unset_addr_list_add(UnsetAddrList* uslist, int offset, struct _Node* node)185 {186 UnsetAddr* p;187 int size;188189 if (uslist->num >= uslist->alloc) {190 size = uslist->alloc * 2;191 p = (UnsetAddr* )xrealloc(uslist->us, sizeof(UnsetAddr) * size);192 CHECK_NULL_RETURN_MEMERR(p);193 uslist->alloc = size;194 uslist->us = p;195 }196197 uslist->us[uslist->num].offset = offset;198 uslist->us[uslist->num].target = node;199 uslist->num++;200 return 0; ↑ free201 }
  20. 20. false positive
  21. 21. BLAST • with CIL OCaml • • assert() • • asserthttp://mtc.epfl.ch/software-tools/blast/index-epfl.php
  22. 22. escape
  23. 23. #include <assert.h>int watched; /* a global variable */void foo(int i) { watched = i; } ←void bar(){  int j;  foo(j);  assert(j == watched);  /* assert(j != watched); */} % gcc -E -I ${BLAST_INCLUDE} -main bar target.c % pblast.opt target.i -main bar :-)
  24. 24. #include <assert.h>int *watched;void foo(int *p) { watched = p; }void bar(){  int i, *j;  i = 1;  j = &i;  foo(j);  assert(j == watched);  /* assert(j != watched); */} % gcc -E -I ${BLAST_INCLUDE} -main bar target.c % pblast.opt target.i -main bar :-)
  25. 25. ruby 1.9 trunk• for while• if •• • •
  26. 26. Frama-C• with CIL OCaml•C • • • value plug-in ← • users plug-in http://frama-c.com/
  27. 27. division by zerovoid foo(int x, int y){ int z = x / y; /* y should not be zero */ return;}int main(int argc, char **argv){ int x = 1, y = 0; foo(x, y); return 0;}
  28. 28. Frama-C value plug-in% frama-c -val foo.c[value] Analyzing a complete application starting at mainfoo.c:3:[kernel] warning: division by zero: assert y ≢ 0;
  29. 29. division by zero • ruby trunk revision no. 33685 • bignum.c • 1044 ds[k] = (BDIGIT)(num / hbase); • util.c • • 331 n = (r - l + size) / size;Frama-C value plugin
  30. 30. Frama-C users plug-in• callee •
  31. 31. void foo(void) {}void bar(void) {foo();}int main(void){ bar(); return 0;} % frama-c -users foo.c [kernel] preprocessing with "gcc -C -E -I. foo.c" [users] ====== DISPLAYING USERS ====== bar: foo main: foo bar ====== END OF USERS ==========
  32. 32. ruby string.ccalleehttp://sovmoess.tumblr.com/post/12364993205/frama-c-ruby-1-9-string-c-callee @ikegami_ _
  33. 33. • • false positive • • CPU• annotation • annotation • Frama-C + jessie plug-in → Coq
  34. 34. •2 C • ruby-1.9 trunk revision 33685• cppcheck/splint • escape• BLAST/Frama-C •

×