Cppcheckの使い方の詳細と設定
前回、Cppcheckの簡単な使い方を紹介しました。 ここでは、もう少し掘り下げて使い方の詳細と設定方法について紹介していきます。 Cppcheckをまだ使ったことが無い方は、こちらから先に。 既にインストールや簡単な使い方を試したことがある方に詳細を説明していきます。 動作環境は、同様に以下の環境です。
- CentOS6.8 x86_64
使い方の詳細
ディレクトリ内の全てのファイルを検査
通常、プログラムはプロジェクトディレクトリ内にある多くのソースファイルから成り立っています。 そのディレクトリ内にある全てのソースファイルをチェックする方法から。
サンプルのコードですと面白くないので、C/C++で書かれたオープンソースをダウンロードしてCppcheckを実行してみました。 サンプルとして選んだソースは、MariaDBのコネクターです。私は、データベースを扱うことが多く、たまたまMariaDBのソースが手元にあったからです。(mariadb-connector-c-2.3.2-src.tar.gz)
1/109 files checked 0% done
Checking mariadb-connector-c-2.3.2-src/examples/mysql_debug.c…
2/109 files checked 0% done
Checking mariadb-connector-c-2.3.2-src/examples/test_output.c…
[mariadb-connector-c-2.3.2-src/examples/test_output.c:67]: (error) Resource leak: fp_out
[mariadb-connector-c-2.3.2-src/examples/test_output.c:67]: (error) Resource leak: fp_exp
Checking mariadb-connector-c-2.3.2-src/examples/test_output.c: _WIN32…
...
...
実行開始して直ぐに、「Resource leak」のエラーが出てきましたが、本当にそこにバグがあるかどうかは、もちろんよく調べなければ分かりません。 cppcheckが誤検出しているかもしれないからです。
あるディレクトリやファイルを検査対象から外す
ディレクトリやファイルを検査対象から外すには、-i オプションを追加します。
これでhogeの配下は検査されなくなります。
重要度
error | バグが見つかった際に使われる。 |
warnning | バグ回避するためのお勧め。 |
style | 綺麗なコードになるように使われていない関数などを表示。 |
performance | コードの実行速度が速くなるようなお勧め手法。 |
portability | 64-bit ポータビリティ。 また別のコンパイラへのポータビリティ。 |
information | 設定に関する問題。 |
これらの重要度の中でerrorだけがデフォルトで表示されます。 ––enable オプションを使うことによってその他についても表示することが可能となります。
全ての重要度を表示するには、––enable=all を付けて実行します。 また例えば、warningとperformanceだけを対象に検査したい場合は、カンマ区切りで ––enable=warning,peformance のように指定します。
Inconclusive check
Cppcheckは、初期設定で確実だと思われるエラーメッセージのみを表示します。 もしこの挙動を変更し、不確かな部分についてもメッセージを出したい場合は、––inconclusive を付けて実行します。
CMakeとVisual Studio
CMakeまたは、Visual Studioを使っている場合は、––project を付けて実行すると良いようです。 例えば、
とすると、cmakeは、コンパイル時のオプションが列挙されたJSONファイルを作成します。 ファイル名は、compile_command.jsonとなりますので、そのファイルを指定して実行します。
Visual Studioを使っている場合は、
のように実行します。
プリプロセッサ
Cppcheckは、ソースコードがプリプロセッサで条件分岐されて何パターンかのコンパイルができるような場合、全パターンについて検査を実行します。 この挙動を変えるには、定数をdefineした状態で実行すると良いようです。
逆にある定数がdefineされていない状態にして実行することもできます。
メモリリーク
malloc等で割りあてられたメモリポインタは、他の関数に渡されていったりすると、その先で解放されるかどうか把握するのが大変です。 Cppcheckも自動で判断することはできないので、ポインタを渡された関数側で解放することをデフォルトで想定しています。 この挙動を変更したい場合は、設定ファイル(XML)を作成し、Cppcheck実行時にそのファイルを指定してあげる必要があります。 例えば、次のコードをtest.cppとして保存します。
1 2 3 4 5 6 |
void some_function() { char *str; str = malloc(sizeof(char) * 10000); str_func(str); } |
str_func関数が、受け取ったポインタでメモリを解放しないのでしたら、次のようにXMLで設定ファイルを準備します。 (例えばファイル名をmemcheck.cfgとして)
1 2 3 4 5 6 7 |
<?xml version="1.0"?> <def> <function name="str_func"> <leak-ignore/> <arg nr="1"/> </function> </def> |
この設定ファイル(memcheck.cfg)をcppcheckに渡して実行します。
[test.cpp:6]: (error) Memory leak: str
逆にもし、str_func関数がメモリを解放するのでしたら、次のようなXMLを準備します。 (ファイル名は同様にmemcheck.cfg)
1 2 3 4 5 6 7 |
<?xml version="1.0"?> <def> <memory> <dealloc>free</dealloc> <use>str_func</use> </memory> </def> |
自分のプロジェクトに合わせて設定ファイルを作るのは少し大変かもしれませんが、一つのツールとして使って見るのはいかがでしょうか? 設定は上記以外にも、いろいろできるようですので、詳細はmanページなどを参考にして試してみて下さい。
この記事へのコメントはこちら
コメントを投稿するにはログインしてください。