People vs. PVS-Studio:最初に取ります

こんばんは、ハブラナロッド!



この投稿とHabrasocietyに励まされて、私はあなたに( Wo1fが顕著に言ったように)よく促進されたユーティリティの分析の私自身のバージョン-PVS -Studioを提供します。



注として、私はVisual Studio 2010(もちろんクラックされた)を使用し、 「ダウンロードして試してみる」をクリックして指示に従ってPVS-Studio を公​​式サイトからダウンロードしました。 私はこのユーティリティについて質問があり、いわばあなたの助けが必要なため、これをすべて書いています。



まず、前の記事のテストを実行します。



テスト1:


int main() { vector<int> v; v.reserve(2); assert(v.capacity() == 2); v[0]; v[0] = 1; v[1] = 2; cout << v[0] << endl; v.reserve(100); cout << v[0] << endl; return 0; }
      
      





VS2010なし

PVS-Studioなし



テスト2:


 void prettyFormat(int i, char* buf) { sprintf(buf, "%4d", i); } int main() { vector<int> v; v.reserve(2); //.... char buf[5]; prettyFormat(10, buf); return 0; }
      
      





VS2010警告C4996: 'sprintf':この関数または変数は安全ではない可能性があります。 代わりにsprintf_sの使用を検討してください。

PVS-Studioなし



テスト3:


 int* prettyFormat(int i, char* buf) { sprintf(buf, "%4d", i); int* a; return a; } int main() { ...
      
      





VS2010警告C4996: 'sprintf':この関数または変数は安全ではない可能性があります。 代わりにsprintf_sの使用を検討してください。

警告C4700:初期化されていないローカル変数 'a'が使用されました



PVS-Studioなし



テスト4:


 int* prettyFormat(int i, char* buf) { sprintf(buf, "%4d", i); int* a; fopen("filename", "r"); char buf2[5]; strcpy(buf2, buf); return a; }
      
      





VS2010 :前の2つに加えて、 警告C4996: 'fopen':この関数または変数は安全でない可能性があります。 代わりにfopen_sの使用を検討してください。

警告C4996: 'strcpy':この関数または変数は安全ではない可能性があります。 代わりにstrcpy_sの使用を検討してください。



PVS-Studioなし



ここに私の質問があります。PVS-Studioが何も提供しないのはなぜですか。3つのレベルの「出力」がすべてオンになっています。 たぶん私は何か間違ったことをしていますか? (メニューからPVS-Studio->ソリューションの確認を選択します)、ユーティリティの「使用」方法がわからなくても笑わないでください。



新しいテスト


そして、続けてください。 思いついた最も簡単な例:

 char buf[32]; strncpy(buf, data, strlen(data));
      
      





PVS-Studioは再びサイレント状態になり、Visual Studioは「安全でない」機能(この場合はstrncpy())を使用するときに起こりうる問題を警告します。

本当の問題は何ですか? 問題は、古典的なバッファオーバーフローであり、多くの人がC / C ++の愛から抜け落ちたエラーであり、残りはこれらの美しい言語に反対する理由を見つけました。 この例では、ターゲットのサイズではなく、入力バッファの長さがstrncpy関数の最後の引数として渡されます!



次のテストはより「プロフェッショナル」レベルで、マルチスレッドに焦点を当てています。 コードスニペット:

 list<unsigned long> a_list; unsigned long get_next() { unsigned long ret = 0; if (!a_list.empty()) { ret = a_list.front(); a_list.pop_front(); } return ret; }
      
      





VS2010なし

PVS-Studioなし



レースが発生する可能性があると思わない場合は、一見、すべてが正常です。 これは競合状態です。2つのプログラムが異なるプロセスまたはスレッドで実行されている場合に発生する可能性があります。 これらのプログラムは相互に割り込むことができ、同時にそれぞれが同じリソースを変更します。 上記の例では、一方のスレッドがリスト内の要素の存在のチェックを終了してから、もう一方のスレッドがpop_frontを呼び出してリストから最後の要素を取得します。



ですから、最初のテイクには十分だと思います。次のテイクでは、このような大規模なアプリケーションの実際のテストを実行する予定です。 idemuraが指摘したように、アナライザーに頼るべきではなく、むしろプロフェッショナリズムのレベルを上げる必要があるだけです。



PS文法の間違いについて...-投稿を遅く書いた。



All Articles