0Pricing
C++ Academy · レッスン

UBSanとTSan

未定義動作とデータ競合を見つけます

「UBSanとTSan」はCoddyKit上の無料C++ Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはC++ Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 C++ Academyコースには全4レッスンが含まれています。

もう2つのサニタイザー

ASan 以外にも、異なる種類のバグを対象とするサニタイザーが2つあります。

  • UBSan:未定義動作(オーバーフロー、不正なシフト、ヌル参照など)
  • TSan:マルチスレッドコードのデータ競合

UBSan を有効にする

UndefinedBehaviorSanitizer は -fsanitize=undefined で有効にします。ASan と組み合わせることもできます。

g++ -fsanitize=undefined -g main.cpp -o app
./app

符号付き整数のオーバーフロー

C++ では、符号付き整数のオーバーフローは未定義動作です。UBSan はそれが発生した正確な行を報告します。

#include <climits>
#include <iostream>

int main() {
    int x = INT_MAX;
    int y = x + 1; // signed overflow: UB
    std::cout << y << "\n";
    return 0;
}

UBSan が検出するその他の未定義動作

UBSan は、見つけにくいさまざまなエラーを検出します。

  • 範囲外のシフト(32ビット整数に対する x << 40 など)
  • ヌルポインターのデリファレンス
  • アラインメントに違反したアクセス
  • 無効な enum 値や bool 値

UBSan を停止させる

デフォルトでは、UBSan はメッセージを表示して実行を続けます。最初のエラーで中断するには -fno-sanitize-recover=undefined を追加します。CI ではこの設定が適しています。

g++ -fsanitize=undefined -fno-sanitize-recover=undefined -g main.cpp -o app

TSan を有効にする

ThreadSanitizer は -fsanitize=thread で有効にします。同期処理なしで2つのスレッドが同じメモリーにアクセスし、そのうち少なくとも一方が書き込む場合に発生するデータ競合を検出します。

g++ -fsanitize=thread -g main.cpp -o app -pthread
./app

データ競合の例

2つのスレッドがロックなしで共有カウンターをインクリメントしています。TSan は競合しているアクセスと、それぞれのスタックを報告します。

#include <thread>
#include <iostream>

int counter = 0;

void work() { for (int i = 0; i < 1000; ++i) ++counter; }

int main() {
    std::thread t1(work), t2(work);
    t1.join();
    t2.join();
    std::cout << counter << "\n";
    return 0;
}

競合を修正する

ミューテックスで共有データを保護するか、std::atomic を使ってください。修正後は、TSan に競合が報告されなくなります。

#include <thread>
#include <atomic>
#include <iostream>

std::atomic<int> counter{0};

void work() { for (int i = 0; i < 1000; ++i) ++counter; }

int main() {
    std::thread t1(work), t2(work);
    t1.join();
    t2.join();
    std::cout << counter << "\n";
    return 0;
}

TSan と ASan の互換性

TSan と ASan は競合するため、同じビルドで組み合わせることはできません。ASan+UBSan 用と TSan 用に、別々のビルド構成を使用してください。

サニタイザービルドの組み合わせ

実用的な CI 構成では、テストスイートを2種類のサニタイザービルドで実行します。

  • ビルド A:-fsanitize=address,undefined
  • ビルド B:-fsanitize=thread

これにより、メモリー、未定義動作、並行性に関するバグをカバーできます。

コストと制限

TSan を有効にすると、プログラムが5~15倍遅くなり、メモリー使用量も大幅に増えることがあります。すべてのサニタイザーと同様に、実行したコードパス上のバグしか検出できないため、質の高いマルチスレッドテストが重要です。

クイックチェック

TSan が検出するものを思い出してください。

まとめ

UBSan と TSan について学びました。

  • UBSan(-fsanitize=undefined)は、オーバーフロー、不正なシフト、ヌル参照を検出します
  • -fno-sanitize-recover で最初の未定義動作が発生した時点で中断します
  • TSan(-fsanitize=thread)はデータ競合を検出し、ミューテックスや atomic で修正します
  • TSan と ASan には別々のビルドが必要です

よくある質問

「UBSanとTSan」レッスンは無料ですか?

はい。「UBSanとTSan」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、C++ Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 C++ Academyコースには全4レッスンが含まれています。

「UBSanとTSan」で何を学びますか?

未定義動作とデータ競合を見つけます ブラウザで直接実行するハンズオンコードでC++ Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

C++ Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのC++ Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。

「UBSanとTSan」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このC++ Academyレッスンでコードを書いて実行できますか?

はい。すべてのC++ Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. gdbとlldbの使用
  2. AddressSanitizer
  3. UBSanとTSan
  4. Valgrindの基礎
← C++ Academyに戻る