Re: [PATCH] ThreadSanitizer warnings for cThread

Marko Mäkelä <[email protected]> Mon, 12 Dec 2022 16:53:46 +0200
Newsgroups gmane.linux.vdr
Message-ID <Y5dAeh8rJ8m2jvJI@jyty>
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
[email protected]
https://www.linuxtv.org/cgi-bin/mailman/listinfo/vdr