自分で作ったオープンソースな C++ ライブラリ, メモリリークやバグの少ない状態で, いろいろな人に安心して喜んで使ってもらえるように, 普段から内面をキレイに保っておきたいですよね!
ここでは C++ のコードを内面からキレイに保つレシピを集めてみました.
(追記) @MitsutakaTakeda さんの C++ コードのデトックスも合わせて読んで, この春, 一歩先行くぬけがけ美ワザを極めちゃお! http://qiita.com/MitsutakaTakeda/items/6b9966f890cc9b944d75
Instruments
MacOSX ユーザであれば, XCode に付属(?)の Instruments がオススメ. GUI でお手軽にメモリのプロファイリングやリークの調査が行えます.
Valgrind
昔からある実行バイナリをインストゥルメントして解析してくれるツール.
メモリ周りのチェックをするなら, --tool=memcheck --leak-check=full
がオススメ.
Sanitizers
Valgrind のようにメモリ周りのバグやリークを探してくれるツール. コンパイル時にオプションを指定してビルド(e.g. -fsanitize=address
)しないといけないという制限がありますが, そのかわり Valgrind などのツールに比べて実行時のオーバヘッドが少ないのが利点です.
ASAN(Address Sanitizer) は昨今の gcc(少なくとも 4.8 以降), clang コンパイラに搭載されているのでお気軽に使えます. 最新版のコンパイラのほうがいろいろ expressive レポートしてくれます.
MSAN(Memory Sanitizer) は現在 x86 + Linux 64bit オンリーとなるので気をつけて.
また, Valgrind との混在は危険なので気をつけましょう(大量にメモリ消費して Out-of-memory 起きたりします).
さらに, CUDA と混ぜると動かないよ(shadow memory あたり設定すればいけるっぽい)
Coverity scan
静的解析ツール.
オープンソースの場合はオンラインで無料で利用できます. delete 忘れや, 未初期化変数のチェックなどをしてくれます.
お気に召したら, 上司へのおねだりリストに商用ライセンスを加えておきましょう.
Travis CI の連携と組み合わせて: https://scan.coverity.com/travis_ci
scan-build
clang ベースの静的解析ツール. MacOSX だとプリコンパイルされたバイナリがあります.
Coverall
カバレッジレポートツール. C++ の場合は gcov フォーマットのカバレッジデータをレポートしてくれます. カバレッジを通らない不要なコードは削除してダイエットに励むのもよいですね!
Travis CI の連携と組み合わせて: https://github.com/eddyxu/cpp-coveralls
LGTM
CodeQL でコードレビューしてくれるよ.
最近 LTGM サービス提供していた Semmle 社 GitHub に買収されました(GitHub で今後 CodeQL サービスが提供されるかも?)
CodeQL(lgtm) + VSCode + C/C++ で静的(?)ソースコード解析をお手軽に極めたいメモ
https://qiita.com/syoyo/items/e0cfe3b5871c8cfe9d23
Fuzzer
LGTM(CodeQL)とはちょっと違う方向でテストパターン多量に作って試す系.
Clangでファジング (-fsanitize=fuzzer)
https://qiita.com/snsinfu/items/67bd5196a53e5575c4b9
セキュリティ系のアプリ開発には役立つかも?
最近は ClusterFuzzLite で Github Actions などの CI で動かすのもできるようになっています.
ClusterFuzzLite でぺろっと C/C++ project の fuzzer を Github actions で走らせるメモ
https://qiita.com/syoyo/items/a87bf95bcdafa9a1e6c0
GCC
GCC 10 から, 静的解析をする -fanalyzer
が追加されています(experimental)
TODO
- Windows 系(Visual Studio 系)でいいのはないかな?
- VS2019 あたりから, MSVC にも experimental で sanitizer サポートされているっぽいので試す.