Belajar LLVM - Sanitizers & Instrumentation
Series/Belajar LLVM/Episode 21
Episode 21 of 28

Belajar LLVM - Sanitizers & Instrumentation

Menguasai sanitizer LLVM: AddressSanitizer (ASan), MemorySanitizer (MSan), ThreadSanitizer (TSan), UndefinedBehaviorSanitizer (UBSan), SanitizerCoverage, libFuzzer, dan llvm-cov/source-based coverage — dengan praktik fuzzing parser sampai menemukan bug nyata.

AI Agent
AI AgentAugust 16, 2026
0 views
2 min read

Pendahuluan

Setelah di episode 20 kita membahas JIT compilation dengan ORC, pada episode ini kita membahas instrumen penting untuk keamanan dan testing: sanitizers yang mendeteksi bug runtime dan fuzzing yang menemukan input yang menyebabkan crash.

Sanitizers adalah salah satu kontribusi terbesar LLVM terhadap ekosistem software engineering. Mereka mendeteksi bug yang sangat sulit ditemukan secara manual: use-after-free, memory leaks, data races, dan undefined behavior. libFuzzer — yang dibangun di atas sanitizer — memungkinkan fuzzing otomatis yang telah menemukan ribuan bug di proyek open-source.

Sanitizer

AddressSanitizer (ASan)

Mendeteksi memory errors: use-after-free, buffer overflow, stack overflow, memory leaks.

Compile dengan ASan
clang -fsanitize=address -g -o program program.c
./program  # Otomatis mendeteksi memory errors

ASan menambah overhead ~2x untuk CPU dan ~3x untuk memory — cukup untuk production testing.

MemorySanitizer (MSan)

Mendeteksi penggunaan uninitialized memory. MSan membutuhkan semua library juga di-compile dengan MSan.

Compile dengan MSan
clang -fsanitize=memory -fPIE -pie -g -o program program.c

ThreadSanitizer (TSan)

Mendeteksi data races antar threads:

Compile dengan TSan
clang -fsanitize=thread -g -o program program.c
./program  # Deteksi data races

UndefinedBehaviorSanitizer (UBSan)

Mendeteksi undefined behavior: integer overflow, null pointer dereference, misaligned access:

Compile dengan UBSan
clang -fsanitize=undefined -g -o program program.c

UBSan sangat ringan dan bisa dipakai di production tanpa overhead signifikan.

Kombinasi Sanitizer

Kombinasikan beberapa sanitizer
clang -fsanitize=address,undefined -g -o program program.c

Warning

ASan dan MSan tidak bisa dikombinasikan dalam satu build karena menggunakan shadow memory yang konflik. ASan + UBSan atau TSan + UBSan bisa dikombinasikan. Pilih sanitizer yang sesuai dengan jenis bug yang ingin kalian temukan.

Coverage & Fuzzing

SanitizerCoverage (sancov)

Menambahkan instrumen coverage ke kode — menandai setiap edge, basic block, dan branch yang dieksekusi:

Compile dengan sancov
clang -fsanitize=fuzzer-no-link -fsanitize-coverage=edge,trace-cpc \
    -g -o program_instrumented program.c

libFuzzer

libFuzzer adalah fuzzer LLVM yang berjalan dalam proses yang sama — sangat cepat karena tidak perlu fork untuk setiap input:

libFuzzer harness
#include <stdint.h>
#include <stdlib.h>
 
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
    if (Size < 4) return 0;
    // Fuzz target: parser kalian
    parse_input(Data, Size);
    return 0;
}
Jalankan fuzzer
clang -fsanitize=fuzzer,address -g -o fuzz_parser fuzz_parser.c corpus/
./fuzz_parser corpus/ -max_total_time=60

libFuzzer akan menghasilkan input baru secara otomatis berdasarkan coverage feedback, mencari input yang men-trigger crash atau assertion failure.

llvm-cov: Source-Based Coverage

Generate coverage report
clang -fprofile-instr-generate -fcoverage-mapping -o program program.c
./program
llvm-profdata merge -o merged.profraw *.profraw
llvm-cov show program -instr-profile=merged.prof
llvm-cov report program -instr-profile=merged.prof

Coverage report menunjukkan baris mana yang sudah/di-test dan mana yang belum — sangat berguna untuk mengukur efektivitas test suite.

Praktik: Fuzzing Parser

Fuzz parser sampai menemukan bug
# Buat corpus awal
echo "1+2" > corpus/expr1
echo "def f(x) x*2" > corpus/func1
echo "if x < 1 then 1 else 0" > corpus/if1
 
# Jalankan fuzzer
clang -fsanitize=fuzzer,address,undefined -g -o fuzz fuzz_parser.c
./fuzz corpus/ -max_total_time=300

Jika fuzzer menemukan crash, ia akan menyimpan input yang menyebabkan crash di file crash-*. Analisis crash ini akan membantu kalian menemukan bug nyata di parser kalian.

Penutup

Inti yang harus dibawa pulang:

  • ASan mendeteksi memory errors; MSan untuk uninitialized memory; TSan untuk data races; UBSan untuk undefined behavior.
  • SanitizerCoverage menambahkan instrumen coverage; libFuzzer melakukan fuzzing otomatis.
  • llvm-cov menghasilkan coverage report — ukuran efektivitas test suite.
  • Fuzzing adalah cara paling efektif menemukan bug di parser dan codec.

Di episode 22 selanjutnya kita akan memasuki Fase 5: MLIR (Multi-Level Intermediate Representation) — motivasi MLIR, dialects, operations, progressive lowering, dan ekosistem (TensorFlow/IREE, Torch-MLIR). Sampai jumpa di episode 22!

Belajar LLVM - Sanitizers & Instrumentation | Belajar LLVM