I just learned yesterday that for GCC '-Wall' does not turn on all the warnings '-Wall' should include unless '-O2' is used as well. Not sure if '-O1' results in a different subset.
From my C experience it's probably to do with pointer arithmetic, since if you loop over with pointers you can do something like _p < a + n_ and a + n would be pointing right after the array
How do the sanitizers compare to the usage of Valgrind? This used to be my tool of choice because I can simply invoke my program with valgrind and it does everything and doesn't require recompilation. Is there a notable performance difference?
One advantage of AddressSanitizer vs. Valgrind is in keeping track of memory - from allocation through deallocation and then additional accesses. Jason didn't demonstrate it, because it only applies when you have pointers pointing at already de-allocated memory. Great for debugging double de-allocations. It ends up telling you "You see that invalid access? That pointer was pointing at memory that thread T0 allocated (and here's the backtrace, with line numbers) and was de-allocated in thread T3 (+backtrace), and your code tried to access it here (+backtrace)." I find that applications run a little faster with AddressSanitizer, but that AddressSanitizer requires more RAM. (Which is a problem when your application consumes most of the available RAM on the machine.) But that's totally anecdotal. I didn't ever measure it.
Valgrind usually has a x20 memory overhead(with a big perf hit) while the sanitizers have ~x1.5-x2. Also, the memory sanitizer for example uses shadow memory(block of memory next to your allocated memory) to detect bugs like out of bounds access and stuff like that - compared to Valgrind, an error with the sanitizers means 100% issue(you did actually access invalid memory, etc...).
Valgrind is so slow because it effectively runs the program in a virtual machine. This is also why it can't reproduce everything that happens when you run your program on real hardware, like crashes due to data races for example.
Why is one-past-end pointer valid at 3:30? I thought one could get that pointer but not dereference it, which would happen inside the string variable `last_arg` constructor right?
Old video, simply a mistake on my part. Here is an example proving it's a mistake: compiler-explorer.com/z/fMo91afWj the most likely scenario (as I can recall) is that I was not getting an ASAN error with that value when I recorded the video.
Sorta related is the c++ core guidelines checker for visual studio. Don't know if it exists for other compilers though. Though that's more static analysis.
Great video Jason. I have one question regarding usage of multiple sanitizers. As you recommend, it would be nice to run unit tests with sanitizers On, however some sanitizers are incompatible with each other (for example, in clang one cannot compile with both flags -fsanitize=memory and -fsanitize=address at the same time). Would it be the case then to compile and run all code and tests for each sanitizer? Thanks again.
MSVC does not have support for them. You can use Clang on Windows though. Sorry but MSVC is not a very good compiler(to put it mildly) so many of the features are not supported on it...
@@Key_C0de MSVC is a horrible compiler, it does its own thing, poorly, has its own syntax and isn't standard compliant like the other compilers. It does windows things good because its designed for windows only.
If I recall that stack variables being defaulted to some initialized variable, but globals being uninitialized. But it may depend on debug/release builds. I'm curious how the warnings/errors change if this was a global. Or I could be completely wrong. Maybe someone could chime in here and correct me?
Thanks a lot Json. Perfect simple explanation of what is sanitizer and Valgrind ep. 86
I just learned yesterday that for GCC '-Wall' does not turn on all the warnings '-Wall' should include unless '-O2' is used as well. Not sure if '-O1' results in a different subset.
Why is what he says at 3:25 true (the element after the array is still valid)? I couldn't find anything about this in the internet.
From my C experience it's probably to do with pointer arithmetic, since if you loop over with pointers you can do something like _p < a + n_ and a + n would be pointing right after the array
How do the sanitizers compare to the usage of Valgrind? This used to be my tool of choice because I can simply invoke my program with valgrind and it does everything and doesn't require recompilation. Is there a notable performance difference?
One advantage of AddressSanitizer vs. Valgrind is in keeping track of memory - from allocation through deallocation and then additional accesses. Jason didn't demonstrate it, because it only applies when you have pointers pointing at already de-allocated memory. Great for debugging double de-allocations. It ends up telling you "You see that invalid access? That pointer was pointing at memory that thread T0 allocated (and here's the backtrace, with line numbers) and was de-allocated in thread T3 (+backtrace), and your code tried to access it here (+backtrace)."
I find that applications run a little faster with AddressSanitizer, but that AddressSanitizer requires more RAM. (Which is a problem when your application consumes most of the available RAM on the machine.) But that's totally anecdotal. I didn't ever measure it.
Valgrind usually has a x20 memory overhead(with a big perf hit) while the sanitizers have ~x1.5-x2.
Also, the memory sanitizer for example uses shadow memory(block of memory next to your allocated memory) to detect bugs like out of bounds access and stuff like that - compared to Valgrind, an error with the sanitizers means 100% issue(you did actually access invalid memory, etc...).
In Windows world I can recommend Visual Leak Detector.
Valgrind is so slow because it effectively runs the program in a virtual machine. This is also why it can't reproduce everything that happens when you run your program on real hardware, like crashes due to data races for example.
Why is one-past-end pointer valid at 3:30? I thought one could get that pointer but not dereference it, which would happen inside the string variable `last_arg` constructor right?
Old video, simply a mistake on my part.
Here is an example proving it's a mistake: compiler-explorer.com/z/fMo91afWj
the most likely scenario (as I can recall) is that I was not getting an ASAN error with that value when I recorded the video.
Sorta related is the c++ core guidelines checker for visual studio. Don't know if it exists for other compilers though. Though that's more static analysis.
Great video Jason. I have one question regarding usage of multiple sanitizers. As you recommend, it would be nice to run unit tests with sanitizers On, however some sanitizers are incompatible with each other (for example, in clang one cannot compile with both flags -fsanitize=memory and -fsanitize=address at the same time). Would it be the case then to compile and run all code and tests for each sanitizer? Thanks again.
In my opinion, set up as many CI runs as you reasonably can to test all of the things you can!
Can anyone help me out with setting up these sanitizers in VS code c++ setup ?
How about similar sanitizers for msvc compilers?
MSVC does not have support for them. You can use Clang on Windows though.
Sorry but MSVC is not a very good compiler(to put it mildly) so many of the features are not supported on it...
msdn.microsoft.com/en-us/library/e5ewb1h3(v=vs.90).aspx
@@Key_C0de MSVC is a horrible compiler, it does its own thing, poorly, has its own syntax and isn't standard compliant like the other compilers. It does windows things good because its designed for windows only.
What should I do if I work with MSVC?
Are there any free sanitizers for MSVC?
Asan is on MSVC too.
docs.microsoft.com/en-us/cpp/sanitizers/asan?view=msvc-160
It is strange that compiler can't detect uninitialized variable on its own...
If I recall that stack variables being defaulted to some initialized variable, but globals being uninitialized. But it may depend on debug/release builds. I'm curious how the warnings/errors change if this was a global. Or I could be completely wrong. Maybe someone could chime in here and correct me?
i have been programming C/C++ years and i am embarrassed to say that this even existed.