web-dev-qa-db-ja.com

メモリ/アドレスサニタイザーとValgrind

解放後のユーザーバグと初期化されていないバグを診断するツールが必要です。私はサニタイザー(メモリおよび/またはアドレス)とValgrindを検討しています。しかし、それらの長所と短所についてはほとんど考えがありません。 SanitizerとValgrindの主な機能、相違点、賛否両論を教えていただけますか?

編集:私は次のような比較を見つけました:ValgrindはDBI(動的バイナリ計測)を使用し、SanitizerはCTI(コンパイル時計測)を使用します。 Valgrindは、SanitizerがValgrind(2x)よりもはるかに高速に実行されるかどうかにかかわらず、プログラムを非常に遅くします(20x)。誰かが私に考慮すべきより重要なポイントを与えることができれば、それは大きな助けになります。

23
kayas

あなたはこれを見つけることができると思います wiki .

消毒剤のTLDRの主な利点は次のとおりです。

  • はるかに小さいCPUオーバーヘッド(Lsanは実質的に無料、UBsanは1.25倍、AsanとMsanは計算負荷の高いタスクでは2〜4倍、GUIでは1.05〜1.1倍、Tsanは5〜15倍)
  • 検出されたエラーの幅広いクラス(スタックおよびグローバルオーバーフロー、リターン後使用)
  • マルチスレッドアプリの完全サポート(マルチスレッドのValgrindサポートは冗談です)

欠点は

  • リソースに制限のある環境(電話など)の制限要因となる可能性のある大きなメモリオーバーヘッド(Asanでは最大2倍、Msanでは最大3倍、Tsanでは最大10倍)。 Valgrindよりもずっと良い
  • より複雑な統合(Asanを理解するためにビルドシステムを教える必要があり、Asan自体の制限/バグを回避する必要がある場合もあり、比較的最近のコンパイラを使用する必要があります)
  • MemorySanitizerは、Msanの下ですべての依存関係(libstdc ++などのすべての標準ライブラリを含む)を再構築する必要があるため、現時点では簡単に使用できません。これは、一般ユーザーは初期化されていないエラーの検出にのみValgrindを使用できることを意味します
  • サニタイザーは通常、相互に組み合わせることはできません(サポートされている組み合わせは、Asan + UBsan + Lsanのみです)。つまり、すべての種類のバグをキャッチするために、個別のQA実行を行う必要があります。
28
yugr

大きな違いの1つは、LLVMに含まれる memory および thread サニタイザーがアドレス空間の巨大なスワスを暗黙的にマップすることです(たとえば、テラバイトのアドレスでmmap(X, Y, 0, MAP_NORESERVE|MAP_ANONYMOUS|MAP_FIXED|MAP_PRIVATE, -1, 0)を呼び出すことでx86_64環境のスペース)。必ずしもそのメモリを割り当てる必要はありませんが、マッピングは制限された環境(たとえば、ulimit値の適切な設定を持つ環境)で大混乱を引き起こす可能性があります。

0
jhfrontz