2011-02-28
CBMCの使い方入門:2
検証 |
次回に向けて、はやくも落ち穂拾い。
double
intだけでなくdoubleでも使えるか、確認。
#include <stdio.h> #include <stdlib.h> #include <assert.h> int main (int argc, char **argv) { int _rand = rand(); double r; #ifdef __CBMC__ __CPROVER_assume(0 <= _rand && _rand <= RAND_MAX); #endif r = (double)(_rand / (RAND_MAX + 1.0)); assert(0.0 < r && r < 1.0); /* わざと範囲を間違えてみる */ return 0; }
このソースをcbmcにかけると、問題を指摘してくれる。
./cbmc test.c -D __CBMC__ --bounds-check --pointer-check ... 略 ... Violated property: file test-a.c line 15 function main assertion 0.0 < r && r < 1.0 FALSE VERIFICATION FAILED
念のため、正しい範囲で再度cbmcにかけると、問題ないと知らせてくれる。
#include <stdio.h> #include <stdlib.h> #include <assert.h> int main (int argc, char **argv) { int _rand = rand(); double r; #ifdef __CBMC__ __CPROVER_assume(0 <= _rand && _rand <= RAND_MAX); #endif r = (double)(_rand / (RAND_MAX + 1.0)); assert(0.0 <= r && r < 1.0); /* 正しい範囲を設定 */ return 0; }
./cbmc test.c -D __CBMC__ --bounds-check --pointer-check ... 略 ... 9473 variables, 37501 clauses SAT checker: negated claim is UNSATISFIABLE, i.e., holds Runtime decision procedure: 0.414s VERIFICATION SUCCESSFUL
関数検査の小技
別関数で確保したメモリ領域の扱いは小技を使う。例えば、以下のように、main()で確保したメモリ領域bufを関数foo()の引数で渡す場合、普通にcbmcにかけるとうまくいかない。
#include <stdio.h> #include <stdlib.h> #include <assert.h> void foo(char *buf) { int i; for (i = 0; i < 10; i++) buf[i] = 'c'; } int main (int argc, char **argv) { char *buf = malloc(10); foo(buf); return 0; }
./cbmc test.c --bounds-check --pointer-check --function foo ... 略 ... Violated property: file test-b.c line 8 function foo dereference failure: dynamic object lower bound !(POINTER_OFFSET(buf) + i < 0) || !(IS_DYNAMIC_OBJECT(buf)) VERIFICATION FAILED
こんなときは、cbmcだけがわかるようにダミーのmalloc()を関数foo()内部で宣言する。
#include <stdio.h> #include <stdlib.h> #include <assert.h> void foo(char *buf) { int i; #ifdef __CBMC__ char *buf = malloc(10); #endif for (i = 0; i < 10; i++) buf[i] = 'c'; } int main (int argc, char **argv) { char *buf = malloc(10); foo(buf); return 0; }
こうすれば、cbmcで検査できる。
./cbmc test.c -D __CBMC__ --bounds-check --pointer-check --function foo ... 略 ... SAT checker inconsistent: negated claim is UNSATISFIABLE, i.e., holds Runtime decision procedure: 0.038s VERIFICATION SUCCESSFUL
これに限らず、ダミーの変数を適度に差し込むのは常套手段のようである。
unwind オプション*1
forやwhileのあるプログラムをcbmcにかけるときは、unwindに十分な回数(forやwhileで実際にまわる回数より多め)を設定しなければならない。
私はうまく説明できないので、詳しいことはこちらのドキュメントを参照されたし。
コメントを書く
トラックバック - http://d.hatena.ne.jp/interdb/20110228/1298836970
リンク元
- 2 http://www.google.co.jp/search?q=CBMC&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:ja:official&hl=ja&client=firefox-a
- 2 http://www.google.co.jp/search?sourceid=navclient&hl=ja&ie=UTF-8&rlz=1T4GGLL_jaJP373JP400&q=innotop+設定+パスワード
- 1 http://b.hatena.ne.jp/kamipo/
- 1 http://d.hatena.ne.jp/diarylist?of=50&mode=rss&type=public
- 1 http://d.hatena.ne.jp/moroto1122/20101207/1291691170
- 1 http://websearch.rakuten.co.jp/?tool_id=1&rid=2000&qt=Postgres-XC
- 1 http://www.bing.com/search?q=mysql+ログ レベル 設定&filt=all&qs=n&sk=&first=21&FORM=PERE2
- 1 http://www.google.co.jp/search?aq=f&sourceid=chrome&ie=UTF-8&q=innotop
- 1 http://www.google.co.jp/search?client=safari&rls=en&q=mytop+mysql&ie=UTF-8&oe=UTF-8&redir_esc=&ei=B2RrTbDvIsX0cNDm2I4M
- 1 http://www.google.co.jp/search?hl=ja&client=firefox-a&hs=axy&rls=org.mozilla:ja:official&q=マスタのバイナリロギング+レプリケー??