Building better software with better tools: sanitizers vs. Valgrind
lemire.me
lemire.me
This is a stretch, IMO. I suppose it is ever-so-slightly-closer.
> They do not bring the safety to production, since you probably do not want to use sanitizers in production or release
You're right, they're not intended for use in production -- until now! ARM dedicated some virtual address bits to tagging memory [1][2][3] for ARMv8 so that we can have sanitizers in hardware. Imagine: chrome on your smartphone being protected!
[1] https://developer.arm.com/docs/ddi0487/latest/arm-architectu...
[2] https://clang.llvm.org/docs/HardwareAssistedAddressSanitizer...
My team runs ASAN in production. We run lots of servers, and we have load balancing that keeps CPU utilization equal across servers. ASAN binaries are slower (maybe 1/2 throughput / 2X "local" cpu-bound latency?) but not so much slower that running it on a small fraction of our servers means we can't meet our SLO. And it's been a huge help to us. Once in a while, we have some segfault that's pretty mysterious otherwise, as the stack trace where memory corruption is discovered can be totally unrelated to the stack trace where the problem was caused. If it happens on the ASAN servers, the root cause is instantly obvious.
TSAN is more problematic to run in production; it's a _lot_ slower.
The conclusions drawn are questionable. The author states that "sanitizers" are fast and "Valgrind-like" tools are slow, but it actually depends on the tool. Some sanitizers are much faster than others. Some dynamic binary translation tools (e.g. DynamoRio's Dr Memory) are much faster than Valgrind. It wouldn't be hard to come up with examples where a compiler-based sanitizer is slower than a dynamic binary translation tool. It all depends on what the tool is actually checking.
Items 3 and 4 are also questionable. It's certainly possible to configure dynamic binary translation tools with customized function-specific behavior. Dynamic translation tools are generally even easier to use than sanitizers because you don't have to modify your build at all, you can just run tests under some kind of wrapper command.
Sanitizers are great tools, too. Maybe you can quibble about his item 3, but he's dead on with item 4. If you have tests, you add a couple compiler flags, and then you'll find memory problems automatically with your unit tests (without much slowdown).
I'd love for fuzzing to be a thing, but even that seems impractical on a large scale (please prove me wrong!) since it's a lot more work than just setting a compile target in cmake and ensuring that sanitizer flags are set for that compile target.
Sanitizers are also very useful there in C/C++ languages because they're mostly runtime checks. In Ada you had them already for a long time, and you can be very through with your checks (see for example validity checks https://gcc.gnu.org/onlinedocs/gnat_ugn/Validity-Checking.ht... , runtime stack size checks https://gcc.gnu.org/onlinedocs/gnat_ugn/Stack-Overflow-Check... , and the very very powerful Initialize_Scalars that has saved me many times https://www.adacore.com/papers/exposing-uninitialized-variab... ).
Shameless plug, but if anyone is interested in an introduction to fuzzing (in Ada) I wrote something some time ago that could be useful : https://blog.adacore.com/running-american-fuzzy-lop-on-your-... .
Fuzzing is fun !
But in practical terms, that's still a lot more than "add this compiler flag" or "swap out this library".
And for God's sake: your users are NOT beta testers!
In the years that I've used the sanitizers, I have yet to discover a false positive. It's always been a real bug.