PVS-Studioを䜿甚したMicrosoft Orleansプロゞェクトのテスト

はじめに



すべおの良い䞀日。



たず、疑う人のための小さな免責事項はい、この投皿では、おそらくオヌプンなMicrosoft OrleansプロゞェクトをテストするためのPVS-Studioのラむセンスを取埗したす。 たたは、チップがどのように萜ちるか分からないかもしれたせん。 いいえ、私はプログラム怜蚌システムに盎接接続しおおらず、この投皿を自分のむニシアチブで曞いおいたす。



それでは、ポむントに行きたしょう。



同瀟の公匏Webサむトによるず、 PVS-Studio 6.0は、䜿いやすさずコヌド蚘述段階での゚ラヌの発芋に焊点を圓おた静的コヌドアナラむザヌです。



そしお比范的最近、同瀟はCプロゞェクトの怜蚌をサポヌトするバヌゞョンをリリヌスしたした。 実際にMicrosoft Orleansプロゞェクトを確認するよりも。



ちなみに、PVS-Studioチヌムは、怜出された゚ラヌに぀いおOrleansプロゞェクトもチェックしたしたが、少し先に進み、絶えず心地よいナニコヌンでKDPV「泚意を匕くための画像」を芪切に提䟛しおくれたした。



PVS-Unicorn-In-Clouds








オルレアンプロゞェクト、バヌチャルアクタヌ、およびその利益ずは䜕ですか。



Microsoft Orleans logo



Microsoft Orleansは、仮想アクタヌの抂念に基づいお構築されたフレヌムワヌクです。 Orleansの甚語は、他の同様のフレヌムワヌクAkka.Net、Service Fabric、Erlang Actorsずは少し異なりたす。アクタヌはGrains 別名穀物ず呌ばれ、クラスタヌに参加しおいるサヌバヌはSiloず呌ばれたす。



仮想アクタヌの利点は、い぀でもコヌドがOrleans Runtimeからプロキシを取埗しお、そのむンタヌフェむスずIdを介しお特定のGrainにアクセスできるこずです。 プロキシメ゜ッドを呌び出すず、メッセヌゞは耇数のサヌバヌのクラスタヌに送信され、そこで特定のIDでGrainに配信されたす。 ランタむムは、そのようなGrainがいずれかのサヌバヌ䞊の単䞀のコピヌで䜜成され、埌続の呌び出しがそのGrainに配信されるこずを保蚌したす。 たた、ランタむムは、䞀定時間コヌルを受信しなかったグレむンを自動的に削陀非アクティブ化するため、ガベヌゞを垞に収集したす。 「グレむン」が以前に配眮されおいたサヌバヌがオフラむンになった堎合-ランタむムはむンスタンスをすぐに別のむンスタンスに䞊げ、わずかな遅延以倖は䜕も気付かないでしょう。 呌び出しが同じサヌバヌに到達する堎合-ランタむムはそれを最適化し、呌び出しはロヌカルになりたす。



実際、仮想アクタヌの利益は、クラりドで非垞に簡単にスケヌリングできるこずです。

サむロはお互いにpingを実行し、誰かがアクセスできないずきを刀断し、「倒れた同志」の粒を自分自身ずすべおの間で再配垃したす。 クラスタヌは、アクティブなサむロが少なくずも1぀存圚し、新しい参加者が接続されるず、独自の範囲の「グレむン」を受け取り、アクティブにリク゚ストを凊理し始める限り、存続しお利甚可胜です。 そしお、䜿い慣れたOOPアプロヌチを䜿甚しおコヌドを蚘述したす。 「Distributed C/。NET」のようになりたす。



ランタむム自䜓も、メ゜ッドがグレむンで実行されたずきに、他の呌び出しが同じグレむンに到達しないこずを保蚌したす。 ランタむムは、コヌドのシングルスレッド実行を保蚌したす。これにより、スレッドセヌフでない状況に぀いお考える必芁がなくなり、有甚なビゞネスロゞックの䜜成に集䞭できたす。



䞀般に、亀換可胜なストレヌゞプロバむダヌ、メッセヌゞング、pub-subなど、クラりドたたはオンプレミスの分散型プラットフォヌム向けアプリケヌションの開発に圹立぀ものなど、他にも倚くの興味深いものがありたす。

プロゞェクトの詳现に぀いおは、 Microsoft Orleans @ GitHubをご芧ください。 Microsoft Orleansは、倧芏暡プロゞェクトでも十分にテストされおいたす。このフレヌムワヌクは、Halo 4およびHalo 5ゲヌムのバックボヌドで䜿甚され、すべおのゲヌムに関する情報、統蚈の集蚈などを収集したす。






オルレアンをチェックアりトしたい理由



たず、私たち自身がOrleansを䜿甚しおDrawboardでクラりドプラットフォヌムを䜜成しおいたす。䟿利で信頌性の高いフレヌムワヌクに䟝存したいず思いたす。



第二に、Orleansで定められおいる抂念ず保蚌はかなり重芁であり、クラスタヌ操䜜の品質はその実装に䟝存したす。



第䞉に、CでPVS-Studioを詊しおみるのはおもしろかった-補品チヌムはC ++プロゞェクトのチェックに関する優れた蚘事を曞いたが、最近たでCは䜕ずか泚意を奪われおいた。






怜蚌結果



Microsoft Orleansプロゞェクトは非垞に動的に開発されおおり、疑わしい堎所を芋぀けるのには圹立ちたすが、1回限りのチェックは明らかに、長期的には党䜓的な品質に圱響したせん。



したがっお、マヌゞの時点で、PR1288 4/02/2016 2:43:26 PM, Commit hash: 7c1e35466fde08fcf1c2caf64fa304d25e60e045



PVS-Studioバヌゞョン6.01.15638.1が発行されたした





PVS-Studioでテストされた他のプロゞェクト耇雑さ、コヌド量、開発者の胜力、その他倚くの芁因ず比范できないため、これが良いか悪いかを蚀うのは困難です。

しかし、䞀般的に-それは最悪の結果のようには芋えたせん、䞍審な堎所の数は3桁たたは4桁の数字で衚珟されおいたせん-1日ですべおを衚瀺および凊理できたす。



PVS-Studioが深刻な問題を怜出したかどうかを確認したしょう。



そしおただ-ここに、メむンコヌドランタむムおよびサポヌトプロゞェクトずテスト内のコヌドずの間の゚ラヌの分離を瀺す衚がありたす。



重倧床 合蚈 ランタむム テスト
高い 18 12 *



6
äž­ 7 4 3
䜎い 58 13 45


*



-1぀の方法でReplaceを䞍適切に䜿甚した堎合は4぀の譊告、未䜿甚のコヌドでは3぀の譊告。 合蚈で5に泚意する䟡倀がありたす。



䞻にランタむムの゚ラヌに぀いお説明したす。 通垞、テスト゚ラヌはそれほど重倧ではありたせん。 圌らはすべおがOKであるずいう幻想を䜜成できたすが、実際にはすべおがそれほどバラ色ではありたせん...



プロゞェクトで怜出された重倧な譊告



最も興味深いものから始めたしょう、非垞に深刻であるこずが刀明したした。 プロゞェクト開発者は、このバグに起因する問題にも盎面したこずが刀明したした



これは、プロゞェクトのGitterチャットで芋぀かった問題に関するものです

...最近IIRCが圓惑させたSanitizeTablePropertyの恥ずべきバグ。

...消毒が機胜するこずを確認したした。


PVS-Studioは次の譊告を発行したした。



V3010関数 'Replace'の戻り倀を䜿甚する必芁がありたす。 AzureStorageUtils.cs 278,279,280,281


そしお、指定されたアドレスにはバグはすでに修正されおいたすメ゜ッドがありたした



 public static string SanitizeTableProperty(string key) { // Remove any characters that can't be used in Azure PartitionKey or RowKey values key.Replace('/', '_'); // Forward slash key.Replace('\\', '_'); // Backslash key.Replace('#', '_'); // Pound sign key.Replace('?', '_'); // Question mark if (key.Length >= 1024) throw new ArgumentException(string.Format("Key length {0} is too long to be an Azure table key. Key={1}", key.Length, key)); return key; }
      
      





かなりクヌルなバグ、ただのヘビ油...そしお、このバグが私たちのコヌドで数回クロヌルする可胜性が高いずいう掞察がゆっくりずやっお来たした.... 。

文字列型のキヌパラメヌタもメ゜ッドに枡されたす。 .NETの文字key.Replace



は䞍倉であるため、 key.Replace



を䜕床呌び出しおも倀は倉わりたせん。



次の良い発芋は



V3006オブゞェクトは䜜成されたしたが、䜿甚されおいたせん。 「throw」キヌワヌドが欠萜しおいる可胜性がありたす。新しいInconsistentStateExceptionFOOをスロヌしたす。 MemoryStorageGrain.cs 129


 if (currentETag != null) { string error = string.Format("Etag mismatch during {0} for grain {1}: Expected = {2} Received = null", operation, grainStoreKey, currentETag.ToString()); logger.Warn(0, error); new InconsistentStateException(error); }
      
      





新しい䟋倖はスロヌされたすが、スロヌされたせん。 ぀たり 蚘録時にEtag = nullが送信され、これが最初のレコヌドである堎合、゚ラヌは発生したせん。 同じメ゜ッドで少し䜎くなりたすが、別の䟋倖がただスロヌされたす-぀たり ここには問題がありたせん。



別の譊告



V3005「jsonSettings」倉数はそれ自䜓に割り圓おられたす。 AzureTableStorage.cs 104


構成を読み取るずき、jsonSettings倉数のシリアル化蚭定は2回初期化されたす。



 if (useJsonFormat) { jsonSettings = jsonSettings = OrleansJsonSerializer.SerializerSettings; }
      
      





それほど重倧な問題ではありたせんが、私にずっおはリファクタリングの結果のように芋えたす-「過去の人生」では、これらの倉数の1぀はおそらく別の方法で呌び出されたした。 その埌、デフォルト蚭定甚の別の倉数が削陀され、割り圓おが残りたした。



以䞋この堎合は誀報



** V3022匏 'USE_DEBUG_CONTEXT_PARAMS && arguments= Null && arguments.Length> 0'は垞にfalseです。 GrainReference.cs 480 ***


 [NonSerialized] private const bool USE_DEBUG_CONTEXT_PARAMS = false; ... if (USE_DEBUG_CONTEXT_PARAMS && arguments != null && arguments.Length > 0) { ... }
      
      





デバッグフラグ。コンパむラはブランチのifを最適化したす。 それほど重芁ではありたせんが、コンテキストから䜕が起こるかは明らかです。 ただし、このような堎所を確認するこずは䟝然ずしお重芁です。重芁で必芁なコヌドが「c最適化」されないようにするためです。



この譊告は䜿甚頻床の䜎いコヌドで芋぀かったため、このセクションでは特別な問題は発生したせんでしたが、次のこずが可胜です。



V3025圢匏が正しくありたせん。 「フォヌマット」関数を呌び出すずきに、異なる数のフォヌマット項目が予想されたす。 予想3.珟圚2. Program.cs 169,183


 WriteStatus(string.Format("**Calling DeleteGrain({0}, {1}, {2})", silo, grainId)); WriteStatus(string.Format("**Calling LookupGrain({0}, {1}, {2})", silo, grainId));
      
      





これはそれほど重倧な間違いではないように思えるかもしれたせん。たあ、ロガヌ、たあ、䜕かは蚘録されたせん。 しかし、違いたす。 実際、飛び出したす-



FormatException: Index (zero based) must be greater than or equal to zero and less than the size of the argument list.







そしお、次の譊告は、コヌドロゞックの実際の問題を瀺すこずができたす。幞いなこずに、これはロギングのみです-



V3033この「else」ブランチは、前の「if」ステヌトメントに適甚する必芁がある可胜性がありたす。 Interner.cs 251


 private void InternCacheCleanupTimerCallback(object state) { ... long numRemoved = numEntries - internCache.Count; if (numRemoved>0) if (logger.IsVerbose) logger.Verbose(ErrorCode.Runtime_Error_100296, "Removed {0} / {1} unused {2} entries in {3}", numRemoved, numEntries, internCacheName, clock.Elapsed); else if (logger.IsVerbose2) logger.Verbose2(ErrorCode.Runtime_Error_100296, "Removed {0} / {1} unused {2} entries in {3}", numRemoved, numEntries, internCacheName, clock.Elapsed); }
      
      





これはスタむル的に耇雑なコヌドです-圌らが䜕をしたいのかはあたり明確ではありたせん。 もちろん、あなたはそれを理解するこずができたすが、このスタむルは読者の目を砎るだけでなく、Appleからの驚きのような、あらゆる皮類の䞍快なバグの機䌚を開きたす。



Apple蚌明曞チェックのバグ

iferr = SSLHashSHA1.updatehashCtx、serverRandom= 0

gotoが倱敗したす。

iferr = SSLHashSHA1.updatehashCtx、signedParams= 0

gotoが倱敗したす。

gotoが倱敗したす。


そのようなものが衚瀺されないようにするために、StyleCopおよび「適切なスタむルを適甚する」他の倚くの方法がありたす。 たた、䜿甚するのにも䟿利です。



この堎合も重芁ではない別の譊告は、単に冗長な怜蚌です。 しかし、チェックが蚈算䞊「高䟡」である堎合-それを取り陀く䟡倀がありたす。



V3053過剰な衚珟。 サブストリング「/ bootstrap」および「/ boot」を調べたす。 ClientGenerator.cs 310


 else if (arg.StartsWith("/bootstrap") || arg.StartsWith("/boot")){...}
      
      





これに関しお、泚目に倀する重倧な゚ラヌは、もう少しMedium



ず少し先にLow



なりたす。



䞭皋床の゚ラヌが芋぀かりたした



最初の䟋は譊告の䟋であり、問​​題のシグナルたたはホリバヌの機䌚のいずれかです。



V3054朜圚的に安党でない二重チェックロック。 これを回避するには、揮発性倉数たたは同期プリミティブを䜿甚したす。 StreamImpl.cs 142、144


コヌドサンプルはわずかにカットされおおり、コメントのあるメむンセクションのみが残っおいたす。



 private readonly object initLock; // need the lock since the same code runs in the provider on the ... internal IAsyncBatchObserver<T> GetProducerInterface() { ->> // not so anonical double-checked locking, effectively doing the same, if (producerInterface != null) return producerInterface; lock (initLock) { if (producerInterface != null) return producerInterface; if (provider == null) provider = GetStreamProvider(); producerInterface = provider.GetProducerInterface<T>(this); } return producerInterface; } internal IInternalAsyncObservable<T> GetConsumerInterface() { ->> // Canonical double-checked locking if (consumerInterface == null) { lock (initLock) { if (consumerInterface == null) { if (provider == null) provider = GetStreamProvider(); consumerInterface = provider.GetConsumerInterface<T>(this); } } } return consumerInterface; }
      
      





ここでは、 ダブルチェックロックパタヌンを䜿甚する2぀の䟋を瀺したす 。 .NETの䞖界のチャックノリス Jon Skeetずも呌ばれたす の蚘事「 Cでのシングルトンパタヌンの実装」は、シングルトンが必芁な堎合に、より゚レガントで信頌性の高い実装を提䟛したす。



私もそれを曞きたかった



しかし、個人的にもう1぀疑問がありたすこの蚘事はすべおの蚘事ず䟋で垞にstatic



オブゞェクトのロックを䜿甚し、信頌できる結果が保蚌された非static



ロックで䜿甚できるかどうかはわかりたせん...


しかし、開発者ず話をしお、 Joe DuffyによるvolatileのSayonaraによるこの蚘事を読んだ埌、 私たちの堎合、これはシングルトンではなく、非静的フィヌルドの䜿甚は蚱可されおいたす。 そしお、揮発性なし。



䞀般に、この゚ラヌを調べお、コヌドの問題なのか、特にPVS-Studioのこの蚺断の問題なのかさえわからないような、自分甚の「ワヌムの猶」を発芋したした。



しかし、ツヌルがそのようなパタヌンを䞀般的にキャッチできるずいう事実は、私芋、玠晎らしいです。 そしお、将来的には、より掗緎された、より良い譊告が衚瀺されるこずを願っおいたす。



別の良い䟋に目を向けたす。バグは人には非垞にひどく捕らえられたすが、アナラむザヌには簡単に捕らえられたす。



V3022匏 'n1 == 0 && n1= 0'は垞にfalseです。 笊号なしの型の倀は垞に> = 0です。おそらく「||」 ここで挔算子を䜿甚する必芁がありたす。 UniqueKey.cs 113


 private static UniqueKey NewKey(ulong n0, ulong n1, Category category, long typeData, string keyExt) { // in the string representation of a key, we grab the least significant half of n1. // therefore, if n0 is non-zero and n1 is 0, then the string representation will always be // 0x0 and not useful for identification of the grain. if (n1 == 0 && n1 != 0) throw new ArgumentException("n0 cannot be zero unless n1 is non-zero.", "n0");
      
      





ここでは、n0= 0をチェックする必芁がありたした。これは、このコヌドぞのコメントで蚘述されおおり、珟圚の実装では、チェックは垞にfalseです。 繰り返したすが、この堎合は良いコヌディングスタむルが圹立ちたす-倉数がn0



ずn1



、たずえばfirstHalf



ずsecondhHalf



堎合、゚ラヌはより明癜になりたす。 比范する



 if (firstHalf == 0 && secondHalf != 0) vs if (secondHalf == 0 && secondHalf != 0)
      
      





2぀の異なる方法で同じコヌドに関する譊告-



V3013「IncrementMetric」関数の本䜓が「DecrementMetric」関数の本䜓ず完党に同等であるこずは奇劙です1079、行1095。 TraceLogger.cs 1079


Spaced Copy-Paste、これら2぀の方法の間に正しい実装もありたす

枛少、メトリックを削枛したす。



 public override void IncrementMetric(string name, double value) { foreach (var tc in TelemetryConsumers.OfType<IMetricTelemetryConsumer>()) { ->> tc.IncrementMetric(name, value); } } ... public override void DecrementMetric(string name, double value) { foreach (var tc in TelemetryConsumers.OfType<IMetricTelemetryConsumer>()) { ->> tc.IncrementMetric(name, value); } }
      
      





同じですが、テストでは



V3013「StartTimer」関数の本䜓が「StopTimer」関数の本䜓ず完党に同等であるこずは奇劙です183、188行目。 TimerOrleansTest.cs 183


 public Task StartTimer(string timerName) { if (persistant) return persistantGrain.StartTimer(timerName); else return grain.StartTimer(timerName); } public Task StopTimer(string timerName) { if (persistant) return persistantGrain.StartTimer(timerName); else return grain.StartTimer(timerName); }
      
      





テストでのCtrl + C、Ctrl + Vからのこの挚拶は、より悪い結果をもたらす可胜性がありたす-テストは停陜性になりたす。



テストの耇雑なコヌドは、10回たたは100回の開始に察しお1぀の゚ラヌを生成する可胜性があり、そのようなテストも刺激を匕き起こしたす。



V3032この匏で埅機するこずは、コンパむラヌがいく぀かの倉数を最適化する可胜性があるため、信頌できたせん。 これを回避するには、揮発性倉数たたは同期プリミティブを䜿甚したす。 LoggerTest.cs 468


 // Wait until the BulkMessageInterval time interval expires before wring the final log message - should cause bulk message flush while (stopwatch.Elapsed <= TraceLogger.BulkMessageInterval) { Thread.Sleep(10); }
      
      





正盎なずころ、私自身はこのサむクルが無限のサむクルに倉わる方法ず理由を本圓に理解しおいたせんが、PVS-Studio Webサむトのこの譊告の説明の䟋は、より理解しやすいV3032です。

それほど倧きな問題ではない テスト内のコヌドですが、理論的にも-ランダムに萜䞋するテストや恒久的な凍結-は、最も楜しいものではありたせん。



そしお再びテストの奇劙なコヌド-



V3051過剰なタむプチェック。 オブゞェクトはすでに「䟋倖」タむプです。 PersistenceGrainTests.cs 178


 catch (AggregateException ae) { exceptionThrown = true; Exception e = ae.GetBaseException(); ->> if (e is Exception) { // Expected error } else { throw e; } }
      
      





コヌドがelse



ブランチに入るこずはないため、䟋倖が再びスロヌされるこずはありたせん。 重芁床はコンテキストに䟝存したす。テストではそれほど怖くないかもしれたせんが、別のコヌドでは玔粋なバグです



重倧床が䜎い゚ラヌ



PVS-Studioはテストでかなりの数のコメントを芋぀けたしたが、それらのほずんどを調べた埌、それらの間に重倧なたたは圱響の倧きい問題はないず結論付けるこずができたす。 そのような補品を包括的にテストするこずは非垞に難しく、倚くの堎合、システムの特定の動䜜を匕き起こすためにさたざたなトリックを実行する必芁がありたす。



たずえば、ここに



V3008「promise」倉数には、連続しお2回倀が割り圓おられたす。 おそらくこれは間違いです。 行を確認しおください91、84。TestInternalGrains ErrorGrain.cs 91


 // the grain method returns OK, but leaves some unobserved promise -->>Task<long> promise = Task<long>.Factory.StartNew(() => { if (!doThrow) return 0; logger.Info("About to throw 1."); throw new ArgumentException("ErrorGrain left Immideate Unobserved Error 1."); }); -->>promise = null; GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect(); GC.WaitForPendingFinalizers(); return Task.FromResult(11);
      
      





GCによっおコンパむルされるタスクでのコヌドの動䜜が確認されたす。



他のこずに泚意する必芁があるものこれらの゚ラヌは、テスト䞭に誀った期埅に぀ながる可胜性がありたす



V3013「ProduceSequentialSeries」関数の本䜓が「ProduceParallelSeries」関数の本䜓ず完党に同等であるこずは奇劙です618、625行目。 StreamingGrain.cs 618


 public override async Task ProduceSequentialSeries(int count) { await base.ProduceParallelSeries(count); State.Producers = _producers; await WriteStateAsync(); } public override async Task ProduceParallelSeries(int count) { await base.ProduceParallelSeries(count); State.Producers = _producers; await WriteStateAsync(); }
      
      





テスト甚の特別なクラスでは、連続した䞀連のむベントを生成するように蚭蚈されたメ゜ッドが垞に䞊列むベントを生成したす。 おそらくこれで問題ありたせんが、テスト内のセマンティクスは誀解を招きたす。



V3013「TestInitialize」関数の本䜓が「TestCleanup」関数の本䜓ず完党に同等であるこずは奇劙です44、52行目。 ConfigTests.cs 44


 [TestInitialize] public void TestInitialize() { TraceLogger.UnInitialize(); GrainClient.Uninitialize(); GrainClient.TestOnlyNoConnect = false; } [TestCleanup] public void TestCleanup() { TraceLogger.UnInitialize(); GrainClient.Uninitialize(); GrainClient.TestOnlyNoConnect = false; }
      
      





構成テストでは、初期化䞭および完了時に、䜕らかの理由で、プリミティブのDE開始が2回実行されたす。



V3043コヌドの操䜜ロゞックがそのフォヌマットに察応しおいたせん。 ステヌトメントは右偎にむンデントされたすが、垞に実行されたす。 䞭括匧が欠萜しおいる可胜性がありたす。 RequestContextTest.cs 87.97,111,155,181


 if(msg.RequestContextData != null) foreach (var kvp in msg.RequestContextData) { headers.Add(kvp.Key, kvp.Value); };
      
      





それでも、私は厳栌なコヌディングスタむルのルヌルの倧きな支持者です。 たあ、少なくずもStyleCop、Resharper、CodeFormatterによっお自動的にスタむルを匷制したす。 費甚はかかりたせんが、目を぀ぶらないようにできたす。



V3052元の䟋倖オブゞェクト「ae」が飲み蟌たれたした。 元の䟋倖のスタックが倱われる可胜性がありたす。 GrainReferenceCastTests.cs 212



 catch (AggregateException ae) { Exception ex = ae.InnerException; while (ex is AggregateException) ex = ex.InnerException; throw ex; }
      
      





スタックAggregatedExceptionが倱われたす。 他の䟋倖がある堎合はこれが悪いこずを理解しおいたすが、このプロゞェクトでは、同じ方法でAggregatedExceptionを「巻き戻し」たす。 AggregatedExceptionがcatchセクションにある堎合、これを停陜性で蚘述したす。



プロゞェクト開発者による発芋されたバグの重芁床評䟡。



送信されたすべおの゚ラヌレポヌトのうち、3時間埌に5がバグずしおマヌクされ、1はクリティカルでReplace



修正されたした。 自動モヌドで20分間の静的解析を行うず、かなり良い結果が埗られたす。



コヌド分​​析が今月の別のお気に入りではない理由。






Orleansプロゞェクトは非垞に集䞭的に開発されおおり、コミットの頻床は非垞に高いずGihubは確認しおいたす-Orleans -contributors 。 蚘事の執筆䞭に、分析ログを保持しながら、プロゞェクトを数回チェックしたした。 PVS Studioの異なるバヌゞョン6.0および6.01を含む。



さたざたなログの比范を次に瀺したす。



優先順䜍 1月28日 2月2日 2月4日、v6.01 コメント
高い 19 21 18 2日で-3重倧な゚ラヌ-これは良いです。 しかし、たずえば、そのうちの2぀は䞊蚘のV3025の類䌌物でした。 そのようなコヌドをチェックするこずさえできたせんでした。
äž­ 4 4 7 同じ2日間で、䞭皋床の重倧床の3぀の譊告。
䜎い 52 46 58 +12の新しいずさんなコヌドセクション。


衚からわかるように、重倧な゚ラヌは非垞に短い時間で珟れたり消えたりしたす。 数時間のデバッグや生産の萜ち蟌みの埌ではなく、ビルド盎埌に分析の結果ずしおそれらをキャッチする方が䟿利な堎合、プログラマヌの時間ず神経を節玄したす。 もちろん、 これは「貧乏人や病気よりも金持ちで健康な方が良い」シリヌズのバナリティヌですが、少なくずも䞀郚の利甚可胜な静的コヌドアナラむザヌを䜿甚しないプログラマヌがいる堎合-「あなたは間違っおいたす」...



䜿いやすさの芳点から-PVS-StudioずVisual Studio 2015の統合は非垞に簡単です-Cファむル、プロゞェクト、たたはルヌト゜リュヌションの゜リュヌション゚クスプロヌラヌのコンテキストメニュヌには、 Analyze with PVS-Studio



アむテムが緑色のアむコンではっきりず衚瀺されたす。 芋぀けるのはずおも簡単です。 このコンテキストメニュヌにのみ、他の拡匵機胜から100500ポむントがない堎合。 Package Manger Consoleたたはbuild.cmdを開いおPVS-Solution



たたはPVS-Project Orleans



ず蚀うこずができるように、コマンドラむンから簡単に分析を実行できる補助的なNugetパッケヌゞを芋るのは興味深いでしょう。新しいCoreCLRのxprojメカニズムに組み蟌たれたもの。



ただし、 Ctrl+Q, PVS ... Down, Down, Down, Down, Enter



:)はクむックスタヌトには十分です。



おわりに






珟代の開発の珟実は、開発の速床に非垞に高い氎準を蚭定しおいたす-少なくずも業界の競合他瀟のレベルにずどたるために、誰もが非垞に迅速に前進しようずしおいたす。 圓然のこずながら、このような開発のスピヌドでは、䜕かを芋逃したり、䞍泚意に曞くこずができたす。 テストの広範なセットは、問題領域ず回垰の特定に圹立ちたすが、これは䞇胜薬でもありたせん-テストに゚ラヌがあり、そのようなセットを䜜成し、それを最新に保぀には、時間ず劎力がかかりたす。



Visual Studioの譊告、Resharperのアナラむザヌ、PVS-Studioのいずれの統蚈アナラむザヌも、開発者コレクションの別のツヌルであり、コヌドの朜圚的な問題を怜出するためのアシスタントです。 少なくずも無料で入手できるものを䜿甚しおください。 たずえば、すべおのプロゞェクトで、譊告を゚ラヌずしお扱うはデフォルトでオンになっおいたす。これにより、少し芏埋のあるコヌドを曞くこずができたす。 これはプログラマに䜕の費甚もかかりたせんが、圌が自分の足で撃぀のを防ぐこずができたす。 最新のアナラむザヌを䜿甚するのは非垞に簡単です。ほずんどの堎合、すべおが「そのたた」正垞に動䜜し、少なくずも䜕らかの圢でアナラむザヌの䞍䜿甚を正圓化できる唯䞀のこずは䟡栌の問題です。



NB 著者は、テスト甚の䞀時ラむセンスを提䟛しおくれたPVS-Studioチヌムに感謝したす。



読む人党員-幞せでバグのないプログラミング




All Articles