読者です 読者をやめる 読者になる 読者になる

write ahead log

ロールフォワード用

cflowを使ってみる[POSIXコマンド]

相変わらずPOSIXコマンドをずっと見ている.(若干飽きてきた)

cflowというソースコード解析ツールがあるらしい.
POSIXコマンドっぽいのだが,Ubuntuだとそもそも入っていない.

それほど高機能でも無いようだけど,コールグラフが出せるらしい.試してみる.

インストール

POSIXコマンドなはずだけどUbuntuには入っていない.(The Open Groupに載ってるのってどういう意味なんだ...)

とりあえず入れる.

sudo apt-get install cflow

確認

twinbird@:~$ cflow -V
cflow (GNU cflow) 1.4
Copyright (C) 2005, 2006, 2009, 2010, 2011 2009 Sergey Poznyakoff
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Sergey Poznyakoff.

解析してみる

解析に使うコードがないと試せもしない.(仕事でなら試してみたいのがたくさんあるが...)
興味もあったのでgitの最初のバージョンにしてみる.

結構小さい.すごいなぁ.

とりあえずinit-db.cがgit initとあたりを付けてコマンドを流してみる.

twinbird@:~/lab/git-e83c5163316f89bfbde7d9ab23ca2e25604af290$ cflow init-db.c 
main() <int main (int argc, char **argv) at init-db.c:3>:
    getenv()
    mkdir()
    perror()
    exit()
    stat()
    S_ISDIR()
    fprintf()
    strlen()
    malloc()
    memcpy()
    sprintf()

おー,なるほど.コールグラフが出るわけね(そりゃそうか)

もうちょっと複雑そうなのでcommit-tree.cで試す.

twinbird@:~/lab/git-e83c5163316f89bfbde7d9ab23ca2e25604af290$ cflow commit-tree.c 
main() <int main (int argc, char **argv) at commit-tree.c:103>:
    get_sha1_hex()
    usage()
    strcmp()
    fprintf()
    getpwuid()
    getuid()
    strlen()
    memcpy()
    gethostname()
    time()
    ctime()
    getenv()
    remove_special() <void remove_special (char *p) at commit-tree.c:75>
    init_buffer() <void init_buffer (char **bufp, unsigned int *sizep) at commit-tree.c:15>:
        malloc()
        memset()
    add_buffer() <void add_buffer (char **bufp, unsigned int *sizep, const char *fmt, ...) at commit-tree.c:23>:
        va_start()
        vsnprintf()
        va_end()
        realloc()
        memcpy()
    sha1_to_hex()
    fgets()
    finish_buffer() <void finish_buffer (char *tag, char **bufp, unsigned int *sizep) at commit-tree.c:57>:
        prepend_integer() <int prepend_integer (char *buffer, unsigned val, int i) at commit-tree.c:47>
        strlen()
        memcpy()
    write_sha1_file()

こりゃいい.思った以上だ.

とても手軽でいい.やることも単純明快だ.

オプション

以下があるようだ.GNUはもっとあるようだが,まぁいいや.

オプション 内容
-d コールグラフを作る深さを指定する
-r 呼び出し先だけでなく,呼び出し元の情報も合わせて表示する
-i 結果に取り込む内容を指定する

-d オプション(depth)はコールグラフを作る深さを指定する.

# 深さ2
twinbird@:~/lab/git-e83c5163316f89bfbde7d9ab23ca2e25604af290$ cflow -d 2 commit-tree.c 
main() <int main (int argc, char **argv) at commit-tree.c:103>:
    get_sha1_hex()
    usage()
    strcmp()
    fprintf()
    getpwuid()
    getuid()
    strlen()
    memcpy()
    gethostname()
    time()
    ctime()
    getenv()
    remove_special() <void remove_special (char *p) at commit-tree.c:75>
    init_buffer() <void init_buffer (char **bufp, unsigned int *sizep) at commit-tree.c:15>:
    add_buffer() <void add_buffer (char **bufp, unsigned int *sizep, const char *fmt, ...) at commit-tree.c:23>:
    sha1_to_hex()
    fgets()
    finish_buffer() <void finish_buffer (char *tag, char **bufp, unsigned int *sizep) at commit-tree.c:57>:
    write_sha1_file()


# 深さ1

twinbird@:~/lab/git-e83c5163316f89bfbde7d9ab23ca2e25604af290$ cflow -d 1 commit-tree.c 
main() <int main (int argc, char **argv) at commit-tree.c:103>:

-r オプション(reverse)は呼び出し元と呼び出し先の両方の情報を出す

twinbird@:~/lab/git-e83c5163316f89bfbde7d9ab23ca2e25604af290$ cflow -r init-db.c 
S_ISDIR():
    main() <int main (int argc, char **argv) at init-db.c:3>
exit():
    main() <int main (int argc, char **argv) at init-db.c:3>
fprintf():
    main() <int main (int argc, char **argv) at init-db.c:3>
getenv():
    main() <int main (int argc, char **argv) at init-db.c:3>
main() <int main (int argc, char **argv) at init-db.c:3>
malloc():
    main() <int main (int argc, char **argv) at init-db.c:3>
memcpy():
    main() <int main (int argc, char **argv) at init-db.c:3>
mkdir():
    main() <int main (int argc, char **argv) at init-db.c:3>
perror():
    main() <int main (int argc, char **argv) at init-db.c:3>
sprintf():
    main() <int main (int argc, char **argv) at init-db.c:3>
stat():
    main() <int main (int argc, char **argv) at init-db.c:3>
strlen():
    main() <int main (int argc, char **argv) at init-db.c:3>

-iオプション(Include)はxまたは_と組み合わせて使う.
これによって結果に取り込むものを指定できる.

指定 内容
-i x 外部・スタティックシンボルも結果に含める
-i _ アンダースコアから始まる関数も結果に含める

twinbird@:~/lab/git-e83c5163316f89bfbde7d9ab23ca2e25604af290$ cflow -i x init-db.c 
main() <int main (int argc, char **argv) at init-db.c:3>:
    getenv()
    DB_ENVIRONMENT
    mkdir()
    perror()
    exit()
    stat()
    S_ISDIR()
    fprintf()
    stderr
    DEFAULT_DB_ENVIRONMENT
    strlen()
    errno
    EEXIST
    malloc()
    memcpy()
    sprintf()

中々使えそうな感じである.