02 Mar 2013, 07:25

CppcheckをEclipse CDTに組み込んで静的解析!C/C++ユーザに嬉しい『cppcheclipse』

Eclipse CDT からCppcheckの結果が見れたら便利だなーなんて思って、Eclipseのプラグインを探してみたら、こんなのを見つけた。

cppcheclipse – Integration for cppcheck with Eclipse (CDT) – Google Project Hosting

なんと語呂がいい名前。座布団一枚だ。 というわけで、試してみる。

環境

  • Eclipse 4.2 Juno
  • Windows 7
  • Cppcheck 1.58(注:1.58でないと、Eclipse 4.2 Junoで動かなかった」

cppcheclipseのダウンロードとインストール

Eclipse CDTとCppcheckはインストールされていることが前提で。
Cppcheckがインストール方法は過去記事を参照ください。

CppCheckでC言語/C++のメモリリーク(解放漏れ)を静的解析で検出する。 | Futurismo

注:cygwinからのcppcheckでは動かないので注意すること。

cppcheclipseのインストールは、ツールバーから[ヘルプ] > [Eclipse マーケットプレイス]を選択して、cppcheckで検索すると見つかるので、インストールを選択。

image

Eclipseでの設定

インストールして再起動したら、ツールバーの[ウィンドウ] > [設定] > [C/C++]を選択する。選択項目にcppcheclipseが現れる。

まず、Cppcheckの実行バイナリを選択する。

image

次に、[設定]を選択して、cppcheck実行時のオプションを選択する。
とりあえずは、”–enable=all”だけでよい。

130302_1.png

 

cppcheckを実行する

プロジェクト・エクスプローラからcppcheckを実行したいファイルやフォルダを選択して、右クリック。[cppcheck] > [run cppcheck]を選択して、実行。

実行の結果、エラーがあった場合は[問題ビュー]から確認できる。
そのまま、該当箇所にもジャンブで移動可能なのが嬉しい。

エディタにも、エラー箇所は赤く表示される。

130302_2.png

 

[Ctrl + Alt + C]がCppcheckの実行に割り当てられている。
これで、アクティブなファイルに対して即座に静的解析が実行できる。とても便利だ。

cygwinにインストールしたcppcheckは使えない

cygwinにインストールしたcppcheckだと、cppcheckの結果を正しくEclipseがパースしてくれない。templateの指定方法が間違ってるようで、”問題”ビューにあらわれてくれない。
下のような感じで、表示されてしまう。

‘{file}:{line},{severity},{id},{message}’

WindowsにインストールしたCppcheckを使うこと。

02 Mar 2013, 02:10

setup.exeはもういらん!Cygwinでコマンドラインからインストール/アップデートする[apt-cyg]を試す

Cygwinをツールをアップデートするときに、いちいちsetup.exeを起動するのが面倒だ 。

LinuxやRubyとかみたいに、コマンドラインからインストール出来ないかなと思って調べたらありました。それが

apt-cyg

です。以下、詳細をメモメモφ(`д´)メモメモ

apt-cygとは

apt-cygとは、apt-getみたいにコマンドラインからツールのインストールやアップデートをするためのコマンド。

GoogleCodeで公開されている。

apt-cyg – A command-line software installer for Cygwin – Google Project Hosting

 

 

apt-cygのインストール方法

事前準備として、以下のコマンドをcygwinに入れておくこと。apt-cygの中で使う。

  • Base/gawk
  • Archive/bzip2
  • Base/tar
  • Net/wget

wgetで取得。

$ wget http://apt-cyg.googlecode.com/svn/trunk/apt-cyg

apt-cygは内部的にwgetを使っている。proxy環境でうまくいかない時は、wgetのプロキシ設定が必要。自分は以下の記事を参考にしました。

実行権限を与えて、パスの通った場所に置く。

$ chmod +x apt-cyg
$ mv apt-cyg /usr/bin

これだけで、インストール完了。簡単簡単。

$ apt-cyg --version
apt-cyg version 0.57
Written by Stephen Jungels

Copyright (c) 2005-9 Stephen Jungels.  Released under the GPL.

ミラーサーバの設定

cygwinの取得先を日本のサーバに指定しておく。

// 32 bit
$ apt-cyg -m http://ftp.iij.ad.jp/pub/cygwin/x86/ update
// 64 bit
$ apt-cyg -m http://ftp.iij.ad.jp/pub/cygwin/x86_64/ update

apt-cygの使い方

helpを参照

$ apt-cyg --help
apt-cyg: Installs and removes Cygwin packages.
  "apt-cyg install <package names>" to install packages
  "apt-cyg remove <package names>" to remove packages
  "apt-cyg update" to update setup.ini
  "apt-cyg show" to show installed packages
  "apt-cyg find <patterns>" to find packages matching patterns
  "apt-cyg describe <patterns>" to describe packages matching patterns
  "apt-cyg packageof <commands or files>" to locate parent packages
Options:
  --mirror, -m <url> : set mirror
  --cache, -c <dir>  : set cache
  --file, -f <file>  : read package names from file
  --noupdate, -u     : don't update setup.ini from mirror
  --help
  --version

リポジトリ(setup.ini)をアップデートする

ローカルで持っているツールの更新情報をアップデートする。

apt-cyg update

ツールをアップデートしてみる

ここでは、すでにインストールされたcppcheckをアップデートしてみる。

既存のcppcheckをまずは削除。

$apt-cyg remove cppcheck

次に、新しいcppcheckをインストールする。

$ apt-cyg install cppcheck

これで、cppcheckのバージョンが1.56から1.58にアップデートされた。

いろんなツールの更新を調べて、一気にアップデートするのはsetup.exeを使ったほうがよさそう。

追記 13/08/12

Cygwinに大きな仕様変更があったようで、32bit版と、64bit版で、Cygwinは分けられたようだ。64bit版には、inetutilsも見つからない・・・。

、久しぶりにapt-cygを実行したらエラー。

$ apt-cyg update
Working directory is /setup
Mirror is http://ftp.iij.ad.jp/pub/cygwin/
--2013-08-12 23:12:06--  http://ftp.iij.ad.jp/pub/cygwin//setup.bz2
ftp.iij.ad.jp (ftp.iij.ad.jp) をDNSに問いあわせています... 202.232.140.143, 202.232.140.144, 2001:240:bb8f::f:300, ...
ftp.iij.ad.jp (ftp.iij.ad.jp)|202.232.140.143|:80 に接続しています... 接続しました。
HTTP による接続要求を送信しました、応答を待っています... 404 Not Found
2013-08-12 23:12:06 エラー 404: Not Found。

--2013-08-12 23:12:06--  http://ftp.iij.ad.jp/pub/cygwin//setup.ini
ftp.iij.ad.jp (ftp.iij.ad.jp) をDNSに問いあわせています... 202.232.140.143, 202.232.140.144, 2001:240:bb8f::f:300, ...
ftp.iij.ad.jp (ftp.iij.ad.jp)|202.232.140.143|:80 に接続しています... 接続しました。
HTTP による接続要求を送信しました、応答を待っています... 404 Not Found
2013-08-12 23:12:06 エラー 404: Not Found。

Error updating setup.ini, reverting

404 Not Found…だと?

原因は、setup.iniが 32bit番と64bit番でディレクトリが分けられるようになったからだった。

http://ftp.iij.ad.jp/pub/cygwin/にアクセスすると、ディレクトリ構造が変更されていた。

ミラーサイトは以下のように、32bitと64bitで区別する必要がある。

// 32 bit
$ apt-cyg -m http://ftp.iij.ad.jp/pub/cygwin/x86/ update
// 64 bit
$ apt-cyg -m http://ftp.iij.ad.jp/pub/cygwin/x86_64/ update

正式版のapt-cygはこの仕様変更には対応していないみたい。forkしたapt-cygをみつけたので、しばらくはこっちを使うのが良さそう。

Cygwinをツールをアップデートするときに、いちいちsetup.exeを起動するのが面倒だ 。

LinuxやRubyとかみたいに、コマンドラインからインストール出来ないかなと思って調べたらありました。それが

apt-cyg

です。以下、詳細をメモメモφ(`д´)メモメモ

apt-cygとは

apt-cygとは、apt-getみたいにコマンドラインからツールのインストールやアップデートをするためのコマンド。

GoogleCodeで公開されている。

apt-cyg – A command-line software installer for Cygwin – Google Project Hosting

 

 

apt-cygのインストール方法

事前準備として、以下のコマンドをcygwinに入れておくこと。apt-cygの中で使う。

  • Base/gawk
  • Utils/bzip2
  • Utils/tar
  • Web/wget

wgetで取得。

$ wget http://apt-cyg.googlecode.com/svn/trunk/apt-cyg

apt-cygは内部的にwgetを使っている。proxy環境でうまくいかない時は、wgetのプロキシ設定が必要。自分は以下の記事を参考にしました。

実行権限を与えて、パスの通った場所に置く。

$ chmod +x apt-cyg
$ mv apt-cyg /usr/bin

これだけで、インストール完了。簡単簡単。

$ apt-cyg --version
apt-cyg version 0.57
Written by Stephen Jungels

Copyright (c) 2005-9 Stephen Jungels.  Released under the GPL.

ミラーサーバの設定

cygwinの取得先を日本のサーバに指定しておく。

// 32 bit
$ apt-cyg -m http://ftp.iij.ad.jp/pub/cygwin/x86/ update
// 64 bit
$ apt-cyg -m http://ftp.iij.ad.jp/pub/cygwin/x86_64/ update

apt-cygの使い方

helpを参照

$ apt-cyg --help
apt-cyg: Installs and removes Cygwin packages.
  "apt-cyg install <package names>" to install packages
  "apt-cyg remove <package names>" to remove packages
  "apt-cyg update" to update setup.ini
  "apt-cyg show" to show installed packages
  "apt-cyg find <patterns>" to find packages matching patterns
  "apt-cyg describe <patterns>" to describe packages matching patterns
  "apt-cyg packageof <commands or files>" to locate parent packages
Options:
  --mirror, -m <url> : set mirror
  --cache, -c <dir>  : set cache
  --file, -f <file>  : read package names from file
  --noupdate, -u     : don't update setup.ini from mirror
  --help
  --version

リポジトリ(setup.ini)をアップデートする

ローカルで持っているツールの更新情報をアップデートする。

apt-cyg update

ツールをアップデートしてみる

ここでは、すでにインストールされたcppcheckをアップデートしてみる。

既存のcppcheckをまずは削除。

$apt-cyg remove cppcheck

次に、新しいcppcheckをインストールする。

$ apt-cyg install cppcheck

これで、cppcheckのバージョンが1.56から1.58にアップデートされた。

いろんなツールの更新を調べて、一気にアップデートするのはsetup.exeを使ったほうがよさそう。

追記 13/08/12

Cygwinに大きな仕様変更があったようで、32bit版と、64bit版で、Cygwinは分けられたようだ。64bit版には、inetutilsも見つからない・・・。

、久しぶりにapt-cygを実行したらエラー。

$ apt-cyg update
Working directory is /setup
Mirror is http://ftp.iij.ad.jp/pub/cygwin/
--2013-08-12 23:12:06--  http://ftp.iij.ad.jp/pub/cygwin//setup.bz2
ftp.iij.ad.jp (ftp.iij.ad.jp) をDNSに問いあわせています... 202.232.140.143, 202.232.140.144, 2001:240:bb8f::f:300, ...
ftp.iij.ad.jp (ftp.iij.ad.jp)|202.232.140.143|:80 に接続しています... 接続しました。
HTTP による接続要求を送信しました、応答を待っています... 404 Not Found
2013-08-12 23:12:06 エラー 404: Not Found。

--2013-08-12 23:12:06--  http://ftp.iij.ad.jp/pub/cygwin//setup.ini
ftp.iij.ad.jp (ftp.iij.ad.jp) をDNSに問いあわせています... 202.232.140.143, 202.232.140.144, 2001:240:bb8f::f:300, ...
ftp.iij.ad.jp (ftp.iij.ad.jp)|202.232.140.143|:80 に接続しています... 接続しました。
HTTP による接続要求を送信しました、応答を待っています... 404 Not Found
2013-08-12 23:12:06 エラー 404: Not Found。

Error updating setup.ini, reverting

404 Not Found…だと?

原因は、setup.iniが 32bit番と64bit番でディレクトリが分けられるようになったからだった。

http://ftp.iij.ad.jp/pub/cygwin/にアクセスすると、ディレクトリ構造が変更されていた。

ミラーサイトは以下のように、32bitと64bitで区別する必要がある。

// 32 bit
$ apt-cyg -m http://ftp.iij.ad.jp/pub/cygwin/x86/ update
// 64 bit
$ apt-cyg -m http://ftp.iij.ad.jp/pub/cygwin/x86_64/ update

正式版のapt-cygはこの仕様変更には対応していないみたい。forkしたapt-cygをみつけたので、しばらくはこっちを使うのが良さそう。

03 Oct 2012, 12:15

地獄の苦しみ、メモリ破壊をCppcheckで華麗に食い止めよう!

前回の記事の続き。

CppCheckでC言語/C++のメモリリーク(解放漏れ)を静的解析で検出する

Cppcheckを利用して、バッファオーバーランを検出したい。

バッファオーバーランとは、バッファオーバーフロー、メモリ破壊、メモリ不正番地アクセスとも言われていて、組込みエンジニアを一瞬のうちに恐怖に戦かせる魔法のぽぽぽぽーんだ。

いろんなパターンのメモリ破壊をCppCheckで検出できるか、遊んでみた。

メモリ解放したあとにアクセスしてしまうパターン

[c]

void buffer_over_run(void)

{

char *p;

p = (char *)malloc(1);

free(p);

*p = 3;

}

[/c]

[text]

$ cppcheck –enable=all memory_leak.c

Checking memory_leak.c…

[memory_leak.c:21]: (error) Dereferencing ‘p’ after it is deallocated / released

[memory_leak.c:21]: (error) Uninitialized variable: p

Checking usage of global functions..

[/text]

関係ないメモリ領域に勝手にデータを書き込んでしまう領域破壊パターン

[c]

void buffer_over_run(void)

{

char *p;

p = (char *)malloc(1);

memset(p,”c”,2);

free(p);

}

[/c]

[text]

$ cppcheck –enable=all memory_leak.c

Checking memory_leak.c…

[memory_leak.c:11]: (error) Buffer is accessed out of bounds.

Checking usage of global functions..

[/text]

配列で宣言した領域をオーバーするパターン

[c]

void buffer_over_run(void)

{

char c[5];

c[5] = 3;

}

[/c]

[text]

$ cppcheck –enable=all memory_leak.c

Checking memory_leak.c…

[memory_leak.c:8]: (style) Variable ‘c’ is assigned a value that is never used

[memory_leak.c:21]: (error) Array ‘c[5]’ accessed at index 5, which is out of bounds.

Checking usage of global functions..

[/text]

インクリメントすることで、知らないうちに不正番地アクセス

[c]

void buffer_over_run(void)

{

char *p;

p = (char *)malloc(1);

p++;

*p = 1;

printf(“%x”,p);

free(p);

}

[/c]

[text]

$ cppcheck –enable=all memory_leak.c

Checking memory_leak.c…

Checking usage of global functions..

[/text]

あれ、検出してくれない・・・・そして

$ ./a.exe
*p = 800482a8
Aborted (コアダンプ)

ちょ・・・・なんとかしてよ。

おまけ

ネットを徘徊していたら、メモリ破壊についての面白い詩をみつけた。

直接引用はチョッと気が引けるので、参考リンクとしてリンク貼っておく。

諸君、私はC言語が好きだ

02 Oct 2012, 23:35

CppCheckでC言語/C++のメモリリーク(解放漏れ)を静的解析で検出する。

メモリ解放漏れ・メモリ二重解放は組込みエンジニアにとって、背筋が凍る単語だ。

それは、即、残業しなさいという意味に転じる。

そこから、泥沼のデバッグにハマることがよくある。

そんな課題をスマートに解決するために、メモリ解放漏れやメモリ二重解放を検出するツール調べてみたので、メモメモ。

オープンソース CppCheckのインストールをしよう

Cppcheckを使うことでメモリ解放漏れを静的解析で見つけることが可能だ。CppCheckはその他にも、アロケーション(確保と解放)の不一致(メモリ二重解放),バッファオーバーランの検出ができる。OSSなので、誰でも無料で利用可能。

CppCheckのダウンロードはココから

Cppcheckの使い方の日本語訳は、以下のサイトで公開されている。

(ものすごく感謝!)今回はこれを参考に自分でも試してみる。

cppcheck 日本語マニュアル – 一人ぼっちの共鳴

cppcheck 英語マニュアルはこちちから

Cppcheckでメモリリークを検出する

Cppcheckを利用するには、–enable=allオプションをつけて以下のコマンド実行。

[text]

cppcheck –enable=all [フアイル名]

[/text]

試しにこんなコードを書いてみた。

memory_leak.c

[c]

#include

#include

int main(void)

{

int *p = NULL;

printf(“*p = %x\n”,p);

p = malloc(10);

printf(“*p = %x\n”,p);

return 0;

}

[/c]

なかなか、喧嘩を売っているコードだけれども、

これをCppCheckでチェックすると、案の定怒られる。(よしよし (^-^))

[text]

$ cppcheck –enable=all memory_leak.c

Checking memory_leak.c…

[memory_leak.c:12]: (error) Memory leak: p

Checking usage of global functions..

[/text]

自分で定義したメモリ獲得/解放関数のメモリリークをチェックする

次に、ユーザ定義したメモリ獲得/解放関数をチェックする。

普通、C標準のメモリ獲得/解放関数を直接使用することはなく、自前の関数でカスタマイズして使用することが多い。メモリアロケート関数を別ファイルで宣言してみる。

hoge_memory.c

[c]

#include “hoge_memory.h”

void *hoge_malloc(void)

{

return malloc(10);

}

memory_leak.c

void hoge_free(void *p)

{

free(p);

}

#include

#include “hoge_memory.h”

int main(void)

{

char *p = NULL;

printf(“*p = %x\n”,p);

p = (char *)hoge_malloc();

printf(“*p = %x\n”,p);

return 0;

}

[/c]

[text]

$ cppcheck –enable=all memory_leak.c hoge_memory.c

Checking hoge_memory.c…

12 files checked 40% done

Checking memory_leak.c…

22 files checked 100% done

Checking usage of global functions..

[/text]

Oh! 検出してくれないYo!!(゜д゜)/

こんなときは、–appendオプションを使用する。

使い方は、

[text]

cppcheck 窶錀-append=<メモリ獲得・解放関数定義file> <静的解析対象file>

[/text]

[text]

$ cppcheck –enable=all –append=hoge_memory.c memory_leak.c

Checking memory_leak.c…

[memory_leak.c:13]: (error) Memory leak: p

Checking usage of global functions..

[/text]

これで、、メモリリークを検出しました。

メモリ二重解放を検出する

おまけ。メモリ二重解放もこのとおり発見できます!スゲー。

[c]

int main(void)

{

char *p = NULL;

printf(“*p = %x\n”,p);

p = (char *)hoge_malloc();

printf(“*p = %x\n”,p);

hoge_free(p);

hoge_free(p);

return 0;

}

[/c]

[text]

$ cppcheck –append=hoge_memory.c memory_leak.c

Checking memory_leak.c…

[memory_leak.c:15]: (error) Deallocating a deallocated pointer: p

[/text]

使われていない関数宣言

[text]

$ cppcheck –append=hoge_memory.c –enable=all memory_leak.c

Checking memory_leak.c…

Checking usage of global functions..

[memory_leak.c:18]: (style) The function ‘hogehoge_special’ is never used

[/text]

23 Sep 2012, 05:37

Cppcheckで静的解析して、Jenkinsで表示してみる。

C/C++用の静的解析ツール、cppcheckを使って、静的コード解析をして、

解析結果をJenkinsで表示する方法を調べてみた。

CppCheckのダウンロード・インストール

以下の公式サイトから入手する。

http://cppcheck.sourceforge.net/

Cygwiinからでも入手ができた。

Cygwin使いの自分は、cygwin の setup経由で入手。

image

CppCheckを実行してみる

公式マニュアルはココ( var 1.56)

コマンドラインから、以下のコマンドを実行する。

[text](フアイル単位)

cppcheck –enable=all hogehoge.c

[/text]

[text](フォルダ単位)

cppcheck –enable=all hogehoge

[/text]

[text]

ex.)

C:\mock_study>cppcheck –enable=all src

Checking src/numlib.c…

12 files checked 22% done

Checking src/sample.c…

22 files checked 100% done

Checking usage of global functions..[/text]

XML形式で結果を出力するには、窶肺ml オプションをつける。

( –xmlツꀀツꀀツꀀツꀀツꀀツꀀツꀀツꀀツꀀツꀀツꀀツꀀツꀀツꀀツꀀ Write results in xml format to error stream (stderr).)

これで、標準エラーでXML形式の結果が出力されるので、

リダイレクトでファイルに記録すればよい。

[text]C:\mock_study>cppcheck –enable=all 窶度ml srcツꀀ 2>cppcheck_result.xml[/text]

( 2> で標準エラーをリダイレクトできるんですねー、知らなんだ ; ~_ ~ ; )

CppCheck Plugin を Jenkinsに入れて、静的コード解析結果をみる

Cppcheck PluginをJenkinsにインストールする。
[Jenkinsの管理] > [プラグインの管理] から Cppcheck Pluginを選択して、インストール。

プロジェクトの[設定] > [ビルド] で、cppcheckのコマンドを追加する。

[ビルド後の処理] に [Publish Cppcheck results]

という項目が追加されているので、選択。

Cppcheck report XMLsという項目に、xmlファイル名を追加する。image

実行結果

Web画面でエラーが確認できる。

クリックすれば、ソースの該当箇所まで飛んでくれる。便利。

image

動作環境

  • Windows 7
  • Cppcheck 1.56
  • Cppcheck Plugin 1.11

参考ページ