On Saturday 08 March 2014 14:25:45 Niall Douglas wrote:
On 8 Mar 2014 at 0:55, Andrey Semashev wrote:
The main cause of false positives is when Boost uses atomics to implement low level primitives such as locks. You need to annotate all CAS lock operations with the fact they are CAS locks - that way a thread sanitiser knows you're serialising code. Otherwise it appears you're riddling your code with race conditions.
I think you're confusing ThreadSanitizer and AddressSanitizer. Double free is never a false positive.
No, but I think you didn't understand my post. Double frees which apparently occur Boost.Thread may in fact be double deletes in upstream code, so if type Foo's destructor has at some point the destruction of say a boost::future<>, double deleting Foo will appear as if Boost.Thread is double freeing. In fact the fault is in upstream code, not Boost.Thread.
That doesn't mean that the error is false positive. It just means that the error is not in Boost.Thread. I didn't say I'm 100% positive that the problem is in Boost.Thread. Although I'd say this looks like the most probable case given that the problem is indicated by multiple libraries, including Boost.Thread itself.
Marking up all of Boost.Thread with all the necessary annotations and fixing up any problems revealed is probably a full (and extremely worthwhile) GSoC.
I'd be careful with such markup. I don't know how exactly ThreadSanitizer works, but if markup means calling some function in runtime then that's probably not an acceptable solution in the context of atomics.
No functions are called in valgrind inserted markup. Just some harmless bytes which act as fingerprints. Normally the CPU skips right over them.
Even nop requires decoding effort, so it does have a cost. And I was referring to ThreadSanitizer markup. Does it use the same markup as valgrind does?