相変わらず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()
中々使えそうな感じである.