Sat, Dec 10, 2022 at 07:30:50PM +0200, Marko Mäkelä wrote:
Because of the heap-use-after-free race condition that was rather
easily reproducible with AddressSanitizer (-fsanitize=address), I
thought that I should finally try to learn to use ThreadSanitizer
(TSAN, -fsanitize=thread in GCC and clang).
https://clang.llvm.org/docs/ThreadSanitizer.html
Because VDR makes use of POSIX thread synchronization primitives, no
additional instrumentation via <sanitizer/tsan_interface.h> should be
necessary.
Before C++11 defined a memory model for multi-threaded applications,
semantics around shared data structures were rather unclear, and I
would guess that most multi-threaded pre-C++11 code bases would trip
ThreadSanitizer. Also, multi-threaded CPUs were rare in the early
days, and the Total Store Order of the x86 is very forgiving, compared
to the weak memory model of ARM (see
https://www.cl.cam.ac.uk/~pes20/cpp/cpp0xmappings.html for some
examples).
https://github.com/google/sanitizers/wiki/ThreadSanitizerPopularDataRaces
gives some examples of races, which seem to be possible in VDR. Since
there are not many virtual member functions in a multithreaded software
component that I maintain, I was not even aware that a vptr could be
modified inside a destructor.
Of course, may be a huge gap between something bad reported by
ThreadSanitizer and something bad actually being rather easily
reproducible. For example, lock-order-inversion potentially causes a
deadlock. An actual deadlock requires an (un)fortunate scheduling of
multiple threads that are acquiring some locks in the opposite order.
The wiki page includes the following:
On architectures other than x86, the cache effects or out-of-order
instruction execution may lead to other subtle problems.
Some race conditions on x86 may be merely about a missing "compiler
barrier", which would prevent reordering some code at compilation time.
On ARM, POWER, RISC-V and other CPUs that implement a weak memory model,
special instructions are needed for guaranteeing the correct memory
ordering, for example, when publishing a dynamically constructed object
in a shared data structure:
https://en.cppreference.com/w/cpp/atomic/memory_order#Release-Acquire_ordering
On the x86, there is no difference between that and relaxed memory
ordering, perhaps expect for "compiler barriers".
Marko
_______________________________________________
vdr mailing list
vdr@xxxxxxxxxxx
https://www.linuxtv.org/cgi-bin/mailman/listinfo/vdr