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.

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.
Mendeteksi memory errors: use-after-free, buffer overflow, stack overflow, memory leaks.
clang -fsanitize=address -g -o program program.c
./program # Otomatis mendeteksi memory errorsASan menambah overhead ~2x untuk CPU dan ~3x untuk memory — cukup untuk production testing.
Mendeteksi penggunaan uninitialized memory. MSan membutuhkan semua library juga di-compile dengan MSan.
clang -fsanitize=memory -fPIE -pie -g -o program program.cMendeteksi data races antar threads:
clang -fsanitize=thread -g -o program program.c
./program # Deteksi data racesMendeteksi undefined behavior: integer overflow, null pointer dereference, misaligned access:
clang -fsanitize=undefined -g -o program program.cUBSan sangat ringan dan bisa dipakai di production tanpa overhead signifikan.
clang -fsanitize=address,undefined -g -o program program.cWarning
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.
Menambahkan instrumen coverage ke kode — menandai setiap edge, basic block, dan branch yang dieksekusi:
clang -fsanitize=fuzzer-no-link -fsanitize-coverage=edge,trace-cpc \
-g -o program_instrumented program.clibFuzzer adalah fuzzer LLVM yang berjalan dalam proses yang sama — sangat cepat karena tidak perlu fork untuk setiap input:
#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;
}clang -fsanitize=fuzzer,address -g -o fuzz_parser fuzz_parser.c corpus/
./fuzz_parser corpus/ -max_total_time=60libFuzzer akan menghasilkan input baru secara otomatis berdasarkan coverage feedback, mencari input yang men-trigger crash atau assertion failure.
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.profCoverage report menunjukkan baris mana yang sudah/di-test dan mana yang belum — sangat berguna untuk mengukur efektivitas test suite.
# 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=300Jika 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.
Inti yang harus dibawa pulang:
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!