PVS-Studioを䜿甚したQtプログラムの静的分析の経隓

画像 この蚘事は、かなり倧きなプログラム珟時点では゜ヌスコヌドを含む1665ファむルの静的解析の最初の経隓の結果です。 さらに、これはMicrosoft Visual Studioを䜿甚した初めおの経隓です。 分析されたプログラムの開発は、Ubuntu、Eclipse CDT、GCCコンパむラでのみ実行されたした。



プロゞェクトの準備



「スタゞオ」に堪胜で、Qtプロゞェクトの開発方法を長い間孊んできた堎合は、このセクションをスキップしおください。 VS2010のプロゞェクトを準備する私の方法は次のずおりです。



Qtフレヌムワヌクに基づいおプログラムを開発しおいるため、プロゞェクトに.proファむルがありたす。 このファむルは、プロゞェクトを生成するための基瀎です。 Qt Webサむト http://doc.qt.nokia.com/stable/qmake-project-files.html には、qmakeを䜿甚しお「スタゞオ」プロゞェクトを生成できるず蚘茉されおいたす。 これを行うには、次のコマンドを䜿甚したす。

$ {QTDIR} \ bin \ qmake.exe -t vcapp -spec $ {QTDIR} \ mkspecs \ win32-msvc2010


次に、プロゞェクトファむル* .vcxprojが衚瀺されたす。これは、「スタゞオ」によっお開かれたす。 これ以䞊の操䜜は必芁ありたせんでした-プロゞェクトは正垞にコンパむルされたした。



PVS-Studioのむンストヌルず構成



むンストヌルは䞍可胜です。ダりンロヌド、むンストヌル、再起動するず、メニュヌに目的のタブ-PVS-Studioがすでにありたす。 私はセットアップに少し手を加えなければなりたせんでした。 私が知らない理由で、プロゞェクトを分析するずきPVS-Studio->゜リュヌションのチェック、PVSはQtヘッダヌファむルQWidget.hやQObject.hなどを芋぀けるこずができたせんが、プロゞェクトぱラヌなしでコンパむルされたす。 この状況を修正するには、プロゞェクト蚭定に移動しプロゞェクトを右クリック->プロパティ、「VC ++ディレクトリ」を遞択し、「ディレクトリを含める」セクションでQtヘッダヌファむルぞのパスを指定したす。 さらに、Qt \ includeのルヌトフォルダヌだけでなく、䜿甚するモゞュラヌサブフォルダヌも含める必芁がありたす。 ぀たり、プロゞェクトがコア、gui、xml、sql、network、webkit、openglモゞュヌルを䜿甚しおいるこずを.proファむルが瀺しおいる堎合は、include、include \ qtcore、inclide \ qtgui、includeを远加する必芁がありたす\ qtxml、むンクルヌド\ qtxmlpatterns、むンクルヌド\ qtsql、むンクルヌド\ qtnetwork、むンクルヌド\ qtwebkit、むンクルヌド\ qtopengl。 これらのアクションを実装するず、PVS-Studioは正垞に動䜜し始めたす。



静的解析



分析には玄4時間かかり、その時点でスノヌボヌドをしおいたした。 それで、それは発芋されたした カテゎリヌ3



このカテゎリでは、 最倧 250件 党䜓の87 %% の譊告「V001。 'file'のコヌドフラグメントを分析できたせん '' 、PVSが特定のファむルの解析に倱敗したこずを報告しおいたす。 倚くの譊告は、moc * .cppなどの自動生成ファむルを参照しおいたす。 PVSがこれらのファむルを解析しようずしない堎合、私にずっおはより䟿利です。



次に人気のある譊告は「V550。 奇劙な正確な比范。 定矩された粟床ずの比范を䜿甚するこずをお勧めしたすfabsA-B<EpsilonたたはfabsA-B> Epsilon 。 」 譊告の分析により、 8぀の停陜性ず1 ぀の停陜性が瀺されたした。



このブロックには次の譊告がありたす。 タむプ 'long'のサむズはLLP64 / LP64デヌタモデル間で異なるこずに泚意しおください '' 

この蚺断メッセヌゞにより、プログラムで䜿甚されおいるすべおの「長い」タむプを芋぀けるこずができたす。

もちろん、プログラムに「long」型が存圚するこず自䜓ぱラヌではありたせん。 ただし、WindowsおよびLinuxで正垞に動䜜する必芁がある移怍可胜な64ビットコヌドを䜜成する堎合、このタむプが䜿甚されおいるプログラムテキストのすべおのフラグメントを確認する必芁がありたす。

WindowsずLinuxは、64ビットアヌキテクチャ甚に異なるデヌタモデルを䜿甚したす。 デヌタモデルずは、int、float、pointerなどの基本デヌタ型のサむズの盞関を意味したす。 WindowsはLLP64デヌタモデルを䜿甚し、LinuxはLP64デヌタモデルを䜿甚したす。 これらのモデルでは、「long」タむプのサむズが異なりたす。

WindowsLLP64では、「long」タむプのサむズは4バむトです。

LinuxLP64では、「long」タむプのサむズは8バむトです。

「long」タむプのサむズの違いにより、ファむル圢匏が互換性がなくなったり、LinuxおよびWindowsで実行されるコヌドを開発するずきに゚ラヌが発生したりする堎合がありたす。 必芁に応じお、PVS-Studioを䜿甚しお、 'long'タむプが䜿甚されおいるすべおのコヌドフラグメントを確認できたす。
私はQtフレヌムワヌクを䜿甚しおいるので、long型を䜿甚するこずは䞀般的に口調が悪いこずを思い出させおください。クロスプラットフォヌム開発にはqint16、qint32およびqint64を䜿甚する必芁がありたす。 唯䞀の問題は、この堎合のPVSの䜿甚がプロゞェクト党䜓の怜玢よりも優れおいるこずです。 結局のずころ、これらの譊告は有料補品であるViva64に適甚されたす。 これらの譊告ではコヌド譊告は無効になっおいたす理解ず線集が非垞に困難になりたす。



プログラムのトラむアルのために分析できなかったずいう譊告

「V111。 可倉数の匕数で関数 'foo'を呌び出したす。 N匕数のサむズはmemsizeです”



カテゎリヌ2



このカテゎリには憂鬱な状況がありたした。䞀般分析無料分析に関連する譊告-4個党䜓の2 ずViva64からの160個の詊隓譊告です。



逆説的に、詊隓的な譊告の倧郚分は「V112。 危険な魔法の数Nが䜿甚されたした。これもカテゎリ3にありたす。原則ずしお、PVSがカテゎリ2に属し、カテゎリ3にある郚分は謎です。 倧たかな怜査で玄90の誀怜出が瀺されたため、この譊告のアナラむザヌを改善する必芁があるず考えおいたす。 真の応答が1぀も芋぀からなかったずさえ蚀えたす。 しかし、私はサンプル党䜓をチェックしたせんでした。なぜなら、詊行錯誀がトリックをしたからです-私は疲れおいたす。 この譊告によるず、マゞックナンバヌは䞻に、さたざたなむンデントずオフセットの蚭定などの描画手順で芋぀かりたした。



無料アクセスアラヌト



「V537。 'X'アむテムの䜿甚法の正確さを確認するこずを怜蚎しおください '' 

アナラむザヌは、コヌドの朜圚的なミスプリントを怜出したした。 このルヌルは、発芋的方法を䜿甚しお、次のタむプの゚ラヌを蚺断しようずしたす。

int x = static_cast <int>GetX* n;

int y = static_cast <int>GetX* n;

2行目では、GetYの代わりにGetX関数が䜿甚されたす。 これは正しいコヌドです

int x = static_cast <int>GetX* n;

int y = static_cast <int>GetY* n;

-誀怜知。 コヌドは次のずおりです。

int width = img_in->width();

int height = img_in->height();



if (width > height) {

if (width > maxWidth) {

height = ( int ) (( float ) maxWidth / width * height);

width = maxWidth;

}

} else {

if (height > maxHeight) {

/**/ width = ( int ) (( float ) maxHeight / height * width);

height = maxHeight;

}

}




* This source code was highlighted with Source Code Highlighter .








「V525。 同様のブロックのコレクションを含むコヌド。 行N1、N2、N3、 の項目X、Y、Z、...をチェックしたす -誀怜知。



有料アクセス譊告



「V401。 構造䜓のサむズは、フィヌルドの順序を倉曎するこずで小さくできたす。 サむズをNバむトからKバむトに枛らすこずができたす 。

アナラむザヌは、メむンメモリの無効な䜿甚に぀ながる可胜性のあるデヌタ構造を怜出したした。

Viva64が無効をアナりンスする構造の䟋を考えおみたしょう。

struct LiseElement {

bool m_isActive;

char * m_pNext;

int m_value;

};

この構造は、デヌタの調敎に関連する64ビットコヌドで24バむトを占有したす。 ただし、フィヌルドの順序を倉曎するず、そのサむズは16バむトを占有したす。 構造の最適化されたバリアントは次のようになりたす。

struct LiseElement {

char * m_pNext;

int m_value;

bool m_isActive;

};

...

珟時点では、これがどのように可胜かを理解するこずはできたせんが、これが真実であれば、これは玠晎らしいこずです。この譊告は私にずっお非垞に圹立ちたす、ありがずう。



カテゎリヌ1



状況はカテゎリヌ2に䌌おいたす 1぀の無料譊告ず119の支払いのみ。



無料の譊告

「V524。 「Foo_1」関数が「Foo_2」関数ず完党に同等であるこずは奇劙です -誀怜知 

const qrealgetXconst {

throw std :: runtime_error "サポヌトされおいない操䜜゚ラヌ";

}



const qrealgetYconst {

throw std :: runtime_error "サポヌトされおいない操䜜゚ラヌ";

}





有料の譊告



「V103。 memsize型から32ビット型ぞの暗黙的な型倉換、

「V104。 算術匏のmemsize型ぞの暗黙的な型倉換、

「V110。 memsize型から32ビット型ぞの戻り倀の暗黙的な型倉換、

「V302。 'foo'クラスのメンバヌ挔算子[]には、32ビット型の匕数がありたす。 ここでmemsize-typeを䜿甚したす -これらの譊告はQt゜ヌスコヌド、特にqtessolator.cppファむルで芋぀かりたした。 真実は、詊行錯誀のために怜蚌できたせんでした。



䞀郚の゚ラヌ、特にV114では、PVS-Studio V121は譊告を耇補したす。 そのため、譊告のリストには、同じ行を参照する同じタむプの譊告の平均4぀のむンスタンスがありたす。



たずめ



ツヌルを䜿甚する感芚は2぀ありたす。 私は自分が独創的なプログラマヌであるずは考えおいないため、このツヌルはより倚くの゚ラヌを明らかにするず想定したした。 実際、修正する䟡倀のあるプロットが1぀ありたした。 自分のこずをひどく考えるか、ツヌルがただ完党に磚かれおいたせん。



このツヌルは、 6個  2.11 の無料アラヌトず278個  97.89 の有料アラヌトを発行したした3番目のカテゎリヌなし。 ほずんど無料ではないので、詊しおさえいられたせん。 V112 マゞックナンバヌに関連する譊告は1぀の誀怜知を䞎えたすが、倚くの譊告がありたす-特に支払いが行われおいるので、チェックにうんざりしたす。



このツヌルを賌入したすか 残念ながら、ありたせん。 倚数の誀怜知のため、セットアップず分析に倚くの時間を費やしたした。 500件近くの譊告に察する1぀の誀怜知は、あたりにも残酷です。 驚くべきこずに、有甚な譊告は3぀のカテゎリに分類されたした最も重芁ではないこずを理解したため。 自動生成されたファむルで250個のアラヌトが芋぀かりたした。 そのようなファむルを凊理から陀倖する事前蚭定たずえば、Qt mocファむルを芋たいです。 䜕よりも、譊告V401に満足したしたサむズを小さくするこずができたす。 これは私が買うものです すべおの譊告を賌入しお、サむズを瞮小し、アプリケヌションの速床を䞊げるこずができたす。



ありがずう



All Articles