関西闇Ruby会議とFFI::Ruby

投稿者 nanki 2011-11-15 14:12:00 GMT

関西闇Ruby会議で発表しました。

内容は最近使う機会の増えたruby-ffi(フィッフィ)の紹介。 その時のスライドです。

ちょっとまとめきれなくて最後のほうにごちゃごちゃと書いてしまっていますが、C/Ruby間で独自の型変換を作れるとあったので試しにVALUE型をRubyのオブジェクトに変換するffi-rubyというのを作ってみました。 実用的なかおりがするけどあんまり使い途ない。

VALUE型の変換これであってるのかなぁ。簡単な恒等性のテストにはパスしてるみたいだけど。


Mac OS X でFrama-Cを使ってRubyを静的解析するメモ

投稿者 nanki 2011-11-06 18:11:00 GMT

@ikegami__さんのFrama-Cを使った実験が面白そうなので試してみた。

試験環境はMacBookAir/Mac OS X Lion/ruby192

インストール

$ brew install ocaml
$ wget http://frama-c.com/download/frama-c-Nitrogen-20111001.tar.gz
$ tar zxf frama-c-Nitrogen-20111001.tar.gz
$ cd frama-c-Nitrogen-20111001
$ ./configure --prefix=...
$ make
$ make install

使ってみる

Rubyのソースツリーに移動する。

$ cd ruby
$ ./configure

記事を参考に、.ext/include/ARCH_NAME/ruby/config.h に以下の行を追加。

#ifndef TRUE
  #define TRUE 1
#endif
#ifndef FALSE
  #define FALSE 0
#endif

解析対象ファイルの一覧を作っておく。

$ vi mainobj
array.c bignum.c class.c compar.c complex.c dir.c dln_find.c enum.c enumerator.c error.c eval.c load.c proc.c file.c gc.c hash.c inits.c io.c marshal.c math.c node.c numeric.c object.c pack.c parse.c process.c random.c range.c rational.c re.c regcomp.c regenc.c regerror.c regexec.c regparse.c regsyntax.c ruby.c safe.c signal.c sprintf.c st.c strftime.c string.c struct.c time.c transcode.c util.c variable.c compile.c debug.c iseq.c vm.c vm_dump.c thread.c cont.c

一覧は、common.mk中のCOMMONOBJSを参考にしている。

Frama-C Nitrogen 20111001 で ruby-1.9.2-p290 を検査するときにどうにもならなさそうな事であげられているファイルのいくつかは、直接コンパイルされることを想定して書かれていないので失敗するようだ。

解析開始

$ frama-c \
  -cpp-extra-args="-U__BLOCKS__ -DRUBY_EXPORT -I./.ext/include/ARCH_NAME -Iinclude" \
  -machdep x86_64 \
  -save ruby.session \
  `cat mainobj` 

-U__BLOCKS__はSnowLeopardから導入されたBlocks(Cの文法を拡張している)を無効にするため。これを無効にしないとparseが失敗する。

-machdep x86_64はARCH_NAMEにあわせたものを$ frama-c -machdep helpの結果から選ぶ。

$ frame-c -load ruby.session -metrics
...(ry)...
[metrics] Syntactic metrics
          -----------------
          ** Defined functions (6297):
          ...(ry)...

          ** Undefined functions (297):
          ...(ry)...

          ** Potential entry points (1694):
          ...(ry)...

          SLOC: 144947
          Number of if statements: 25635
          Number of assignments: 40691
          Number of loops: 3651
          Number of calls: 31176
          Number of gotos: 7496
          Number of pointer access: 50736

$ frame-c -load ruby.session -users -main rb_ary_new
...(ry)...
[users] ====== DISPLAYING USERS ======
        ary_alloc: rb_newobj
        ary_new: rb_newobj ary_alloc
        rb_ary_new2: rb_newobj ary_alloc ary_new
        rb_ary_new: rb_newobj rb_ary_new2 ary_alloc ary_new
        ====== END OF USERS ==========
参考: