Closed GoogleCodeExporter closed 9 years ago
I afraid you need to rebuild the libstdc++ (or libc++) with tsan.
https://code.google.com/p/thread-sanitizer/wiki/CppManual#FAQ
Original comment by konstant...@gmail.com
on 28 Jul 2014 at 9:56
Thanks for the very fast reply!
OK, I have to admit that I've never built my own std library. Do you know of
any instructions/how-to I could turn to? Also, do you have any tips for how to
integrate this into my build env? I'll have to keep the tsan-instrumented
library aside somewhere and, when building for tsan, adjust the linker flags
accordingly. Any best-practice for that?
Original comment by michij.h...@gmail.com
on 28 Jul 2014 at 9:32
+knowledgable people for building of libc++
we already do this in chromium, right?
Original comment by dvyu...@google.com
on 29 Jul 2014 at 5:16
Building libc++ is pretty straightforward. You'll have to check out both libc++
and libc++abi. Something like this should work:
clang++ -gline-tables-only -O2 -fPIC -std=c++11 -fstrict-aliasing -nostdinc++
-nodefaultlibs -lc -lgcc_s -lpthread -lrt -Ilibc++/trunk/include
-Ilibc++abi/trunk/include -shared -fsanitize=thread -o libc++.so
libc++/trunk/src/*.cpp libc++abi/trunk/src/*.cpp
This builds the libc++ DSO. To build your code:
clang++ -Ilibc++/trunk/include -Ilibc++abi/trunk/include -nostdinc++
-stdlib=libc++ -std=c++11 -fsanitize=thread x.cpp
You may need to provide the path to your libc++ DSO (since it's not installed
in the system), either through RPATH or LD_LIBRARY_PATH.
Original comment by earth...@google.com
on 30 Jul 2014 at 2:21
Thanks heaps for that info! I got the instrumented version of libc++ built and,
once I link against that, I no longer get the noise from thread sanitizer for
my little test program, which is awesome!
But now I'm running into another issue, trying to use the instrumented library
with my real project. I'm building a library, plus a bunch of executables.
Everything compiles fine with the include files from trunk. But, when it comes
to linking an executable, I get lots of undefined symbol errors. These all
point to libraries that my own library and executables depend on, such as boost
and various other system libraries.
My makefiles are generated with cmake, and I've not been able to come up with
the correct magic incantation for getting the build to pick up my instrumented
library. I don't have libc++ installed and have been linking with gcc's
libstdc++ so far. So, in a pinch, I could even drop my instrumented version
into the file system, rather than trying to set tons of build flags to resolve
this. (Assuming that it's OK to link something like the installed boost with
the version of libc++ I built from trunk, which may well not be the case; I
don't know whether trunk is still binary compatible with boost 1.55…)
I'm sorry to be such a nag here, but I'd much appreciate any other pointers you
might have. I looked at http://libcxx.llvm.org, but I'm not sure how that
relates to my situation.
Original comment by michij.h...@gmail.com
on 4 Aug 2014 at 6:58
If your system libraries depend on libstdc++, then unfortunately you won't be
able to use them with libc++. You'll have to rebuild Boost and everything else
against libc++. I'm afraid I don't have any experience to share here.
Perhaps an easier option would be to suppress the reports coming from libc++. I
think glider@ used to do this in Chromium. so maybe he can chime in here.
Original comment by earth...@google.com
on 4 Aug 2014 at 12:39
Turns out glider is OOO. I've checked the Chromium suppressions file pre-libc++
transition:
http://src.chromium.org/viewvc/chrome/trunk/src/tools/valgrind/tsan_v2/suppressi
ons.txt?pathrev=266010
but couldn't find anything relevant to your case. I will be OOO until the end
of August as well, so I won't be able to help you. You could probably try to
write your own suppressions for those reports, or rebuild Boost as suggested
above.
Original comment by earth...@google.com
on 4 Aug 2014 at 2:36
We did not use std::thread/shared_ptr, so we did not have suppressions for
them. But we had suppressions for std::string:
50 # See http://crbug.com/181502
51 race:_M_rep
52 race:_M_is_leaked
Original comment by dvyu...@google.com
on 4 Aug 2014 at 3:54
Thanks for your comments everyone!
Hmmm... Rebuilding all my dependencies is not a particularly attractive option.
It's not only boost, but about half a dozen other libraries, such as Cap'n
Proto, zmqpp, and so on.
Adding suppressions is something I considered, and actually tried. But there
are two concerns for me here.
- It's not always simple to decide that particular race is actually a false
positive, so it's a lot of work.
- I'm worried that adding suppressions may suppress not only the bogus reports
I'm getting, but may be hiding a real race elsewhere in my code, especially
when the offending function is somewhere in the bowels of a run-time library
that is called from many places (both my own code and code in libraries I link
against). For example, if I suppress _M_rep, can I be sure that, by doing so,
I'm not going to hide a real issue in my code elsewhere?
From reading the doc, it seems that I can only specify a single function for a
suppression. Is that correct?
One thing that might help to mitigate this would be suppressions that work
along the lines of valgrind, where it is possible to specify several stack
frames, so I can selectively apply suppressions to a specific call site. Is
this something you are considering for thread sanitizer?
Original comment by michij.h...@gmail.com
on 4 Aug 2014 at 10:23
> - It's not always simple to decide that particular race is actually a false
positive, so it's a lot of work.
We know that this one is a false positive. How many do you see after
suppressing this one?
> I'm worried that adding suppressions may suppress not only the bogus reports
I'm getting
Yes, that is possible.
> One thing that might help to mitigate this would be suppressions that work
along the lines of valgrind
We moved exactly in the opposite direction: from valgrid suppressions to
single-line suppressions. I've looked at existing suppressions, and it turned
out that 99% of them were single-line. It's difficult to write and maintain
good multi-line suppressions. What multi-line suppresion would you use for this
report?
I would do something like:
race:__shared_count
or if there are lots of other false positives, then:
called_from_lib:libstdc++.so
Original comment by dvyu...@google.com
on 5 Aug 2014 at 6:47
As far as the std library is concerned, this is the only false positive I'm
currently aware of. Unfortunately, some of the libraries I'm linking against
are racy, and I don't get much of a choice about this.
For example, there is a race between malloc/free in a library. I want to
suppress that, but I don't get much of stack trace:
==================
WARNING: ThreadSanitizer: data race (pid=14746)
Write of size 8 at 0x7d200000bb80 by thread T7:
#0 free <null>:0 (ObjectAdapter_test+0x0000000e2dbb)
#1 <null> <null>:0 (libzmq.so.3+0x00000001aff2)
Previous write of size 8 at 0x7d200000bb80 by main thread:
#0 malloc <null>:0 (ObjectAdapter_test+0x0000000e27bd)
#1 <null> <null>:0 (libzmq.so.3+0x00000001ae70)
#2 TestBody /home/michi/src/devel/test/gtest/scopes/internal/zmq_middleware/ObjectAdapter/ObjectAdapter_test.cpp:359 (ObjectAdapter_test+0x000000151846)
#3 void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) /usr/src/gtest/src/gtest.cc:2078 (ObjectAdapter_test+0x000000222b80)
What I would like to say here is "suppress the malloc/free race in libzmq, but
not elsewhere, but I'm not sure that's possible right now?
I see similar races for new/delete, with very similar stacks, as well as races
with malloc/memcpy, etc.
If I just suppress all races for memcpy, I'll easily end up shooting myself in
the foot by suppressing a real race involving memcpy in my own code.
Original comment by michij.h...@gmail.com
on 5 Aug 2014 at 6:59
You can use called_from_lib suppression to suppress everything in a particular
dynamic library:
https://code.google.com/p/thread-sanitizer/wiki/Suppressions?ts=1409666982&updat
ed=Suppressions
Original comment by dvyu...@google.com
on 2 Sep 2014 at 2:10
Is there anything else we can help with? If so please reopen the issue.
Original comment by dvyu...@google.com
on 2 Sep 2014 at 2:11
Thanks for adding the library suppression, that is useful!
Longer term, I suspect that multi-line suppressions along the lines of valgrind
will turn out to be necessary. That's because it's entirely possible that a
library contains benign races that are false positives (due to use of lock-free
techniques) but, at the same time, my code may be using the library incorrectly
elsewhere, causing a real race in the library. For example, zmq sockets are not
thread-safe, and it is entirely possible for me to write code that is broken
and causes a real race somewhere inside libzmq. Suppressing everything that
goes wrong in a library is too coarse because actions taken by the library may
result in real races as well as false positives, but I only want to suppress
the false positives.
Would you consider adding more fine-grained control to the suppressions file?
I didn't re-opened the bug. Should this be submitted separately as a feature
request?
Original comment by michij.h...@gmail.com
on 3 Sep 2014 at 10:14
Just a drive-by comment: TSan should not produce false positives on lock-free
algorithms, if they use atomic operations correctly. If they don't then these
algorithms are broken.
Original comment by samso...@google.com
on 3 Sep 2014 at 10:27
>> Would you consider adding more fine-grained control to the suppressions file?
So far we don't want to do this.
Original comment by konstant...@gmail.com
on 4 Sep 2014 at 1:02
If libzmq is not instrumented, then tsan won't produce any useful reports in
it. So you just need to ignore it all (add called_from_lib suppression).
If you want to find incorrect usages of libzmq, then you need to build a
tsan-instrumented version of the library and remove called_from_lib
suppression. Then tsan will start producing real informative reports that you
will be able to selectively suppress (e.g. race:zmq_foo_bar).
Original comment by dvyu...@google.com
on 4 Sep 2014 at 3:34
>>>> Would you consider adding more fine-grained control to the suppressions
file?
>>So far we don't want to do this.
Assume this means that TSAN does not match on line number, as in following?
race:src/api/src/MXLock.cpp:97
Original comment by wtor...@gmail.com
on 22 Sep 2014 at 5:09
No, it doesn't. It would be very fragile.
So far it matches function name, file name and module, separately, w/o line
numbers.
Original comment by dvyu...@google.com
on 22 Sep 2014 at 5:18
Original issue reported on code.google.com by
michij.h...@gmail.com
on 28 Jul 2014 at 9:54