0Pricing
C++ Academy · 강의

UBSan과 TSan

정의되지 않은 동작과 경쟁 상태 찾기

UBSan과 TSan은(는) CoddyKit의 무료 C++ Academy 강의입니다. 이것은 4개 중 3번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 C++ Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. C++ Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

두 가지 새니타이저 더 알아보기

ASan 외에도 서로 다른 종류의 버그를 대상으로 하는 새니타이저가 두 가지 더 있습니다.

  • 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이 찾는 다른 UB

UBSan은 미묘한 오류를 많이 표시합니다.

  • 범위를 벗어난 시프트(32비트 정수에서 x << 40)
  • 널 포인터 역참조
  • 정렬되지 않은 접근
  • 유효하지 않은 열거형 또는 불리언 값

UBSan에서 실행 중단하기

기본적으로 UBSan은 오류를 출력하고 계속 실행합니다. -fno-sanitize-recover=undefined를 추가하면 첫 번째 오류에서 중단하므로 CI에 더 적합합니다.

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

TSan 활성화

ThreadSanitizer는 -fsanitize=thread로 활성화합니다. TSan은 데이터 경합을 탐지합니다. 즉, 두 스레드가 동기화 없이 같은 메모리에 접근하고 그중 하나 이상이 쓰기 작업을 수행하는 경우입니다.

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

데이터 경합 예시

두 스레드가 잠금 없이 공유 카운터를 증가시킵니다. 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 설정에서는 두 가지 새니타이저 빌드로 테스트 모음을 실행합니다.

  • 빌드 A: -fsanitize=address,undefined
  • 빌드 B: -fsanitize=thread

이렇게 하면 메모리, UB, 동시성 버그를 다룰 수 있습니다.

비용과 한계

TSan은 프로그램을 5~15배 느리게 하고 훨씬 더 많은 메모리를 사용할 수 있습니다. 모든 새니타이저와 마찬가지로 실행된 코드 경로에서만 버그를 찾으므로, 좋은 다중 스레드 테스트가 중요합니다.

빠른 확인

TSan이 무엇을 탐지하는지 떠올려 보세요.

복습

UBSan과 TSan을 배웠습니다.

  • UBSan(-fsanitize=undefined)은 오버플로, 잘못된 시프트, 널 포인터 역참조를 찾습니다
  • -fno-sanitize-recover를 사용하여 첫 번째 UB에서 중단합니다
  • TSan(-fsanitize=thread)은 데이터 경합을 찾으며, 뮤텍스나 원자 연산으로 해결합니다
  • TSan과 ASan은 별도의 빌드가 필요합니다

자주 묻는 질문

“UBSan과 TSan” 강의는 무료인가요?

네 — “UBSan과 TSan” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 C++ Academy 강의 전체를 잠금 해제할 수 있습니다. C++ Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

“UBSan과 TSan”에서 뭘 배우나요?

정의되지 않은 동작과 경쟁 상태 찾기 브라우저에서 직접 실행하는 실습 코드로 C++ Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

C++ Academy을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 C++ Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 3번째 강의입니다.

“UBSan과 TSan” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 C++ Academy 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 C++ Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. gdb와 lldb 사용하기
  2. AddressSanitizer
  3. UBSan과 TSan
  4. Valgrind 기초
← C++ Academy(으)로 돌아가기