We have all been there. You submit your solution, wait anxiously, and then see the dreaded Runtime Error on test 2. Is it an array out-of-bounds index? A signed integer overflow? A null pointer dereference? Usually, you have to stare at your code or add a dozen printf statements to find out. But there is a better way.



By using compiler sanitizers and debug flags, you can make your compiler tell you exactly which line caused the error and why. Here is how to set up a powerful debugging environment on both Linux and Windows.
For Linux Users
Linux makes this incredibly easy with GCC. Instead of your standard compilation command, use the following flags to catch errors at runtime. g++ -g -O2 -fsanitize=undefined -fsanitize=address -fno-omit-frame-pointer -D_GLIBCXX_DEBUG main.cpp -o main.out && timeout 10s ./main.out
What do these flags do?
- -g: Generates debug information. This ensures that when the program crashes, the error message points to the specific line number in your code.
- -O2: Optimizes the code. (Note: You can also use -Og which is specifically designed for debugging, but -O2 mimics the judging environment closer).
- -fsanitize=undefined (UBSan): Catches Undefined Behavior, such as signed integer overflows, division by zero, and invalid bitwise shifts.
- -fsanitize=address (ASan): The MVP of debugging. It catches memory errors like out-of-bounds array access, use-after-free, and stack-buffer-overflow.
- -fno-omit-frame-pointer: Helps the sanitizer generate better stack traces so you can see the chain of function calls leading to the crash.
- -D_GLIBCXX_DEBUG: Enables debug mode for the C++ Standard Library (STL). This checks for things like accessing vector[i] where i is out of size, or dereferencing invalid iterators.
- timeout 10s: Ensures the code runs no more than 10 seconds.
For Windows Users
Getting sanitizers (specifically AddressSanitizer) to work on Windows with MinGW is notoriously difficult. However, we can achieve a perfect setup using Clang and MSYS2.
Don't worry—this setup fully supports bits/stdc++.h and ext/pb_ds(policy-based data structures).
Step 0: Install MSYS2
Download and install MSYS2 (msys2-x86_64.exe) from msys2 website.
Add the binary path to your Windows Environment Variables (Path): C:\msys64\ucrt64\bin
Step 1: Install Compilers and Tools
Open the MSYS2 UCRT64 terminal and run the following to install Clang, LLVM, and necessary libraries:
pacman -S mingw-w64-ucrt-x86_64-clang mingw-w64-ucrt-x86_64-lld mingw-w64-ucrt-x86_64-compiler-rt mingw-w64-ucrt-x86_64-libc++ mingw-w64-clang-x86_64-compiler-rt mingw-w64-ucrt-x86_64-llvm
Step 2: Configure Sanitizer Runtime
We need to copy specific sanitizer libraries to where the linker expects them. Run this entire block in your MSYS2 UCRT64 shell:
mkdir -p /c/msys64/ucrt64/lib/clang/21/lib/x86_64-w64-windows-gnu; \
for f in /c/msys64/clang64/lib/clang/21/lib/windows/*; do cp "$f" \
"/c/msys64/ucrt64/lib/clang/21/lib/x86_64-w64-windows-gnu/$(basename \
"${f/-x86_64/}")";
done
cp /c/msys64/clang64/bin/libclang_rt.asan_dynamic-x86_64.dll /c/msys64/ucrt64/bin/
(Note, if this command fails, replace 21 with the installed version. write echo $(clang -dumpversion | cut -d. -f1) to get it)
Step 3: Set Default Linker:
Run in MSYS2 UCRT64 shell:
echo "-fuse-ld=lld" > "/ucrt64/bin/$(clang++ -dumpmachine).cfg"
Step 4: Precompile Header (Speed Boost)
Compiling with clang++ can be slow. To speed this up, we precompile bits/stdc++.h.
Make sure to use the exact same flags here as you will when compiling your code later.
Run in MSYS2 UCRT64 shell:
clang++ -x c++-header \
-std=c++20 -g -O2 -fsanitize=undefined -fsanitize=address -fno-omit-frame-pointer -fno-sanitize-recover=all -D_GLIBCXX_DEBUG \
-fpch-instantiate-templates /c/msys64/ucrt64/include/c++/$(g++ -dumpversion)/x86_64-w64-mingw32/bits/stdc++.h -o /c/msys64/stdc++.h.pch
Step 5: Compile and Run
Now, you can compile your C++ code with full runtime error checking using the precompiled header (from any terminal or IDE).
But make sure to use exact same flags which were used to precompile the header!
clang++ -std=c++20 -g -O2 -fsanitize=undefined -fsanitize=address -fno-omit-frame-pointer -fno-sanitize-recover=all -D_GLIBCXX_DEBUG \
-include-pch C:/msys64/stdc++.h.pch \
main.cpp -o main.exe
Bonus: Measuring Time on Windows
Linux users have the handy /usr/bin/time command. We can get similar functionality on Windows via MSYS2.
Install the time package: pacman -S time
Run with timeout: Use this command to run your executable. It limits execution time (e.g., 10 seconds) and prints time taken.
C:/msys64/usr/bin/time -f "%esec" C:/msys64/usr/bin/timeout 10s ./main.exe
** Remember to use UCRT64 shell for compiler setup steps. You may use CMD / Powershell / Sublime / Vim / VS Code while compiling.
Happy debugging!









Auto comment: topic has been updated by oweMeEternity (previous revision, new revision, compare).
Auto comment: topic has been updated by oweMeEternity (previous revision, new revision, compare).
For Mac User?
i think you need only install GCC from terminal, then compile program from command on linux
A note on the
timecommands: regulartimeis a shell built-in, not an external program. What's known as/usr/bin/timeis an external program that's just typically installed in the folder/usr/bin. If you don't have it (which is quite common), you need to install it. If you have a shell that has thetimebuiltin, you need to type the full path or the weak builtin will be used.