これらのすべてのエラーでプログラムはどのように機能しますか?

これらのすべてのエラーでプログラムはどのように機能しますか?

私たちのチームは、多数の開いているプロジェクトをチェックして、PVS-Studioアナライザーのエラー検出機能を実証します。 記事の後に、「プログラムはこれらのエラーをどのように処理しますか?」という質問がよく聞こえます。 私はそれに答えようとします。



はじめに



私たちのツールにまだ慣れていない読者のための紹介文。 C / C ++で書かれたアプリケーションのソースコードのエラーを見つけるために、PVS-Studioアナライザーを開発しています。 彼ができることを示す最良の方法は、開いているプロジェクトをチェックし、それらのエラーを見つけることです。 データベースで見つかったエラーを収集します 。 プロジェクトで、私たちの意見で興味深いエラーを見つけた場合、記事を書いています。 更新された記事のリストをご覧ください



だから、私たちの記事を読んで、プログラムが一般的にどのように機能するのか疑問に思っている人もいます。 プログラマー、この状況は驚くべきことではないと思います。 それらのそれぞれは、2年間コード内に安全に住んでいたバグを修正することに成功しました。 したがって、このノートは、プログラミングとはほとんど関係のない読者や、キャリアを始めたばかりのプログラマーを対象としています。 しかし、私の意見では、真面目なプログラマーもここで興味深く有用な考えを見つけることができます。



最も重要なこと



さまざまなコードがさまざまな頻度で実行されます。 コードの一部のセクションは、プログラムが起動するたびに実行されます。一部のケースでは、非常にまれに実行されるセクションがあります。



コードが実行される頻度が少ないほど、コードのエラーを簡単に隠すことができます。 例でこれを説明しようとします。



エラーが原因で大きなボタンがメインプログラムウィンドウに表示されない場合、このエラーはすぐに認識されます。 そして、ほとんどの場合、プログラマーはエラーを修正し、テスト部門に行くことさえしません。



エラーが入力データに依存している場合、彼女が非表示にするのはすでに簡単です。 プログラマーがグラフィックエディターを開発していると想像してください。 彼は、アプリケーションを100x100および300x400の解像度で写真でテストしました。 そして、彼は悪いコードを書いたが、すべてが彼のために働いた。 幸いなことに、同社にはテスト部門があり、100x10000の解像度の細長い画像ではプログラムが機能しないことに気付きました。 エラーはもう少し長生きしたことに注意してください。



エラーが発生すると、特別な条件が必要になるため、エラーはより秘密になります。 当社のグラフィックエディタは、中サイズおよび大サイズの画像に最適です。 しかし、1x1の画像を特別な方法で処理する必要があり、プログラマーもテスターもこの動作モードをチェックすることを考えていないとします。 その結果、1ピクセルの画像を誤って作成したユーザーに対してプログラムがクラッシュします。 今回はエラーがユーザーに届きました。



エラーを検出するのはさらに困難です。 たとえば、非標準の状況を処理する必要のあるコードで見つけることができます。 例は、ファイルをディスクに書き込めないことです。 このような間違いはプログラムで何年も続くことがあり、誰もそれを知らないでしょう。 ハードディスクの容量が不足しているために、ユーザーが重要なデータを保存しない場合にのみ検出されます。 実際、プログラムはこれについて警告し、ファイルを別の場所に保存するように提供する必要がありました。 しかし、ミスのために、彼女は服用して倒れました。



質問への回答



PVS-Studioを使用して開いているプロジェクトをチェックするときに検出するエラーのほとんどは、数千人のユーザーのプログラムの日常作業に影響しません。 それらはすべて、非常にまれにしか使用されないコードセクションに配置されるため、これらのエラーは発生しません。



それ以外のことはできません。 例としてQtライブラリを取り上げます。 このライブラリはデバッグおよびテストされています。 世界中の膨大な数の開発者が使用しています。 表面にエラーが存在することはあり得ません。 したがって、PVS-Studioの助けを借りて、めったに現れないものだけを見つけます。 たとえば、次の関数を考えてみましょう。



QV4::ReturnedValue QQuickJSContext2DPrototype::method_getImageData(....) { .... qreal x = ctx->callData->args[0].toNumber(); qreal y = ctx->callData->args[1].toNumber(); qreal w = ctx->callData->args[2].toNumber(); qreal h = ctx->callData->args[3].toNumber(); if (!qIsFinite(x) || !qIsFinite(y) || !qIsFinite(w) || !qIsFinite(w)) .... }
      
      





関数にエラーが含まれています。 「h」の値はチェックされません。 代わりに、変数「w」が二重チェックされます。 これは間違いですか? はい、これは間違いです。 しかし、彼女が自分自身を証明する確率は非常に小さいです。



まず、Qtライブラリを使用するすべてのアプリケーションがmethod_getImageData()関数を呼び出すわけではありません。 おそらく、それを使用する人はほとんどいません。 第二に、最後の引数が誤って変換された場合にのみエラーが現れます。 他のすべての引数は正しく処理されます。 第三に、この最後の引数を誤って指定する必要があります。 したがって、このエラーが現れる確率は非常に小さいです。



そのため、PVS-Studioを使用して発見されるまで、彼女は長い間Qtライブラリコードに住んでいました。 ところで、誰かがライブラリのチェックについてもっと読みたい場合は、記事「 Qt 5フレームワークのチェック 」をご覧になることをお勧めします。



まとめると。



開発および保守のプロセスにあるプログラムは、さまざまな方法(単体テスト、回帰テスト、手動テストなど)でテストされます。 明示的なエラーは、開発者自身と製品のユーザーの両方が頻繁に遭遇するため、すぐに解消されます。



したがって、Chromiumなどの有名な信頼できるプロジェクトでPVS-Studioアナライザーを起動すると、ほとんど現れないエラーのみを見つけることができます。



つまり、エラーがあります。 それらの多くもあります(チェックN1N2N3N4 )。 しかし、Chromiumを起動すると、それらに遭遇する可能性は低くなります。 エラーを含むコードブランチに入るためには、努力する必要があり、場合によっては非常に大きくなります。



PVS-Studioは必要ありませんか?



この場所を読んだ後、急いで誤った結論を下すことができます。「PVS-Studioが不要になったら、何らかの形で軽微なエラーが発生したら」



通常、このような結論を導き出すことができると感じたら、読者に記事「 Leo Tolstoy and Static Code Analysis 」に精通してもらいます。 しかし、ここでもう一度答えを定式化しようと思います。



実際、私たちの記事とプロジェクトの1回限りのチェックは、静的コード分析の方法論の使用とは無関係です。 1回限りのチェックでは、製品が適切に宣伝されますが、それ以上のものはありません。 それらからの本当の利点はほとんどありません。 利益は、プロジェクトの定期的な分析からのみ得られます。



あなたができる最悪のことは、リリースの少し前にアナライザを実行することです。 これにはダメです。 この瞬間までに分析装置が発見できる膨大な数のエラーは、汗と血を犠牲にして修正されます。 これらは効果的ではありません( 50時間を無駄に過ごす方法の例)。 そして、デバッガーで眠れない夜、テスターとの会話の後、開発者はアナライザーを起動し、いくつかの有用なメッセージのみを受け取ります。 結局、彼らは多くの時間と労力を費やして、最悪の事態をすべて自分で修正しました。 なんで? これはある種の壮大な失敗です。



しかし、私は誇張していません。 開発者は、コードアナライザーの使用方法を理解していないことがよくあります。 多くの場合、手紙には次のように書かれています。 リリース前に使用します。」 これは悲しいです。 したがって、私は考えたくない暗いバグやプログラマーの領域に何度も光をもたらします。



アナライザーがすべてのエラーを検出できると言っているのではありません。 彼は一部だけを見つけるでしょう。 しかし、その後、彼はすぐにそれを行います。 プログラマーが別のコードを書き終えるとすぐに。



静的分析の考え方は、多くのエラーとタイプミスを早期に発見できるということです。 定期的に使用すると、欠陥の検索と修正に費やす時間を大幅に短縮できます。



PVS-Studioが必要です!



最後にあなたを納得させるために、私は1つの実用的な例を挙げます。 最近、Unreal Engineゲームエンジンのすべてのエラーをチェックして修正しました。 ほとんどのエラーは重大ではありません。 これは自然なことです。 多くの重大なエラーが発生します;開発でアンリアルエンジンを使用する人はいません。



ある時点で、アナライザーは0の診断メッセージを発行し始めました。 しかし、開発者はコードを変更して編集します。 そして、アナライザーは新しいコードに関連する警告を再度発行し始めました。 そして、新しいバグがコードにどのように侵入するかをリアルタイムで確認できることがわかりました。 おそらく数日でそれらは除去されますが、アナライザーがそれらをすぐに検出する場合、なぜ気にします。 そのようなエラーの1つを次に示します。



 static void GetArrayOfSpeakers(....) { Speakers.Reset(); uint32 ChanCount = 0; // Build a flag field of the speaker outputs of this device for (uint32 SpeakerTypeIndex = 0; SpeakerTypeIndex < ESpeaker::SPEAKER_TYPE_COUNT, //<== ChanCount < NumChannels; ++SpeakerTypeIndex) { .... } check(ChanCount == NumChannels); }
      
      





&&演算子の代わりに、誤ってコンマを書きました。 そのような間違いは取るに足らないとは言えません。 彼女はバージョン管理システムに入り、間違いなく問題を引き起こすでしょう。 幸いなことに、PVS-Studioアナライザーは警戒していました。



Epic Gamesでの作業の歴史について詳しく知りたい場合は、「 PVS-StudioチームがUnreal Engineコードをどのように改善したか 」という記事を読むことをお勧めします。



おわりに



プロジェクトでPVS-Studioコードアナライザーを延期して試さないことをお勧めします。 こちらからダウンロードできます。 アナライザーのインターフェースは非常にシンプルですが、記事「 PVS-Studio for Visual C ++をご覧になることをお勧めします。 アナライザーを使用する際に役立つヒントを見つけることができます。 たとえば、多くの人は、サードパーティのライブラリを分析結果からどれだけ簡単かつ迅速に除外できるかを認識していません。



メイクファイルまたは独自のビルドシステムを使用してビルドする場合、 PVS-Studio Standaloneはプロジェクトの検証に役立ちます。 このツールには、コンパイラの起動を追跡するメカニズムがあります。



警告の数が怖い場合は、特別なデータベースを使用する新しいメッセージマークアップモードを試してください。 アイデア:すべてのメッセージは面白くないと見なされ、表示されません。 新しいコードに関連するメッセージのみが表示されます。 通常のコード分析の便利さと便利さをすぐに理解できます。 詳細: 「静的解析をプロジェクトに組み込む方法」



頑張って!



All Articles