Changes between Version 44 and Version 45 of BestPracticeHandbook


Ignore:
Timestamp:
Jun 11, 2015, 10:58:45 PM (7 years ago)
Author:
Niall Douglas
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • BestPracticeHandbook

    v44 v45  
    372372 Thread sanitiser (GCC and clang only):: If your library is capable of threaded use or your unit testing creates threads, you definitely should soak execute your unit tests with the thread sanitiser (`-fsanitize=thread`) for a few hours per week which provides a good quality check of the correct use of the C11/C++11 atomic memory model e.g. are all your atomic acquires matched with atomic releases in the right order? Did you read a memory location which was written concurrently without an acquire-release serialisation lock? Sadly the tool can't detect use of memory fences which substantially reduces your flexibility when writing with atomics, so do bear that in mind.
    373373
    374 Some may note I didn't recommend the address sanitiser (GCC and clang only). This is because you need to recompile your STL and libc and all libraries with the address sanitiser to achieve perfect coverage, plus valgrind detects far more problems and valgrind detects bad code generated by the compiler and memory corruption by third party libraries. The only real additional feature of the address sanitiser over valgrind is that it can detect memory corruption within the stack, which valgrind never can. I personally have not found stack corruption much of a problem as programs inevitably crash when it happens. However if valgrind is just far too slow for your testing then employing the address sanitiser can be a useful substitute for valgrind for certain tests only. Note that the address sanitiser is perfect for untrusted input fuzz testing as it is much faster than valgrind, so I recommend the address sanitiser in the next section.
     374Some may note I didn't recommend the address sanitiser (GCC and clang only). This is because I have personally found the better approach to be to design your unit and functional testing to be valgrind friendly, and moreover valgrind is fire-and-forget easy: what problems it reports have the correct information about the cause (if you don't compile all third party libraries with the address sanitiser you can get inaccurate cause reports), and the things it detects (illegal reads and writes, use of uninit values, use of unaddressable memory, illegal/double frees, and memory leaks) are precisely those which are the most common and the ones you definitely need to do per-commit.
     375
     376However, the address sanitiser is superior to valgrind under these circumstances:
     377
     378* If you are running on Microsoft Windows (winclang does a great job of slotting into as if MSVC nowadays with only a very few caveats).
     379* If the code you are testing cannot be adjusted to execute in a reasonable time under valgrind.
     380* If you really do need maximum performance before all else e.g. it is perfect for untrusted input fuzz testing (next section) and I recommend the address sanitiser strongly there.
     381* If you suspect you are seeing memory corruption of your stack or your static data as valgrind cannot check these. Personally speaking I haven't found stack corruption goes undetected especially if you have the undefined behaviour sanitiser always turned on (including release builds) and combined with `-fstack-protector-strong`, so in terms of features the only win here is static data corruption in exchange for not detecting use of uninit values. I'd take the latter any day over the former.
    375382
    376383