*From:* cfe-dev [mailto:cfe-dev-bounces@lists.llvm.org] *On Behalf Of *Hahnfeld,
Jonas via cfe-dev
*Sent:* Thursday, February 11, 2016 9:33 AM
*To:* Alexey Samsonov
*Cc:* mclow.lists@gmail.com; cfe-dev@lists.llvm.org
*Subject:* Re: [cfe-dev] Sanitizer test failures when switching to libc++
by default
*From:* Alexey Samsonov [mailto:vonosmas@gmail.com <vonosmas@gmail.com>]
*Sent:* Thursday, February 11, 2016 1:07 AM
*To:* Hahnfeld, Jonas
*Cc:* cfe-dev@lists.llvm.org
*Subject:* Re: [cfe-dev] Sanitizer test failures when switching to libc++
by default
*From:* cfe-dev [mailto:cfe-dev-bounces@lists.llvm.org] *On Behalf Of *Hahnfeld,
Jonas via cfe-dev
*Sent:* Wednesday, February 10, 2016 7:43 AM
*To:* Alexey Samsonov
*Cc:* cfe-dev@lists.llvm.org
*Subject:* Re: [cfe-dev] Sanitizer test failures when switching to libc++
by default
*From:* Alexey Samsonov [mailto:vonosmas@gmail.com <vonosmas@gmail.com>]
*Sent:* Wednesday, February 10, 2016 1:54 AM
*To:* Hahnfeld, Jonas
*Cc:* Kostya Serebryany; cfe-dev@lists.llvm.org
*Subject:* Re: [cfe-dev] Sanitizer test failures when switching to libc++
by default
*From:* Alexey Samsonov [mailto:vonosmas@gmail.com]
*Sent:* Friday, February 05, 2016 11:05 PM
*To:* Kostya Serebryany
*Cc:* Hahnfeld, Jonas; cfe-dev@lists.llvm.org
*Subject:* Re: [cfe-dev] Sanitizer test failures when switching to libc++
by default
Hi all,
I'm currently looking into (optionally) switching the default C++ stdlib to
libc++ (see ⚙ D15920 [CMake] Add option to switch default C++ stdlib which hasn't received a review
so
far)
I've resolved all regression test failures in clang which are now passing
cleanly.
I'm now investigating the failing sanitizer tests in compiler-rt, here's
what I got so far:
- two tests use -static-libstdc++ which obviously needs a
-stdlib=libstdc++
(asan/TestCases/throw_invoke_test.cc and tsan/static_init6.cc)
Makes sense.
I wonder if we can also use -static-libc++ for these tests
At least in my build there is not static version of libc++… I think this
isn’t built by default but I haven’t yet searched for an opt-in.
- tsan builds an instrumented version of libc++ and adds their headers.
This leads to errors with default C headers which are #include_next'd in
libc++. These #include_next then find the headers of the "normal" libc++
which in turn instantly return because of the header guards. Therefore
basic
functions like printf aren't defined.
Solution: Pass -nostdinc++ to disable the headers of the "normal" libc++
emm, probably.
Just to clarify: do you want to pass it to TSan lit tests? How would you
ensure that
we'll still pick up C++ standard library headers when tests are run with
Clang configured
to use libstdc++?
I’m planning on passing it in test/tsan/lit.cfg around line 57. Those
flags are only applied if an instrumented version of libcxx is available
and there is an explicit definition of the header include path, so this
should work.
I see. Yes, probably -nostdinc++ would work in this case.
- lsan completely fails with libc++, I had to generally pass
-stdlib=libstdc++ - is this known and possibly still work in progress?
This is not known to me. What are the symptoms?
“LeakSanitizer has encountered a fatal error” on all C++ tests. This is
fixed when building the tests with “-stdlib=libstdc++”, everything else
still built with libc++…
I also can’t debug with gdb because the errors seems to not occur inside a
debugger
is there any special trick with the sanitizers inside a
debugger that I have not found yet?
LSan uses ptrace to stop the program and list all its threads, the same as
GDB. So, LSan is sadly special in this case. You can try to gain more
insight into what's happening by running the binary
with smth. like LSAN_OPTIONS=verbosity=1:log_pointers=1:log_threads=1
(apart from LSAN_OPTIONS specified in each lit test case).
Thanks for the hint, I will try and see whether I can get some reliable
information…
--
Ok, so here are my findings so far:
verbosity=1 revealed the output “Tracer caught signal 11: […]”
So I disabled the signal handler and the core-file told me that it died
when dereferencing the first TLS address in “ScanRangeForPointers()” in
lib/lsan/lsan_common.cc.
(this also explains the behavior within gdb: It then can’t attach to the
thread and therefore doesn’t crash on scanning TLS)
For me it looks like “ThreadSelf()” in
lib/sanitizer_common/sanitizer_linux_libcdep.cc reports a wrong address…
I can reproduce this with a small C++ program that only contains an empty
main: It crashes with –fsanitize=leak –stdlib=libc++ and works fine with
–stdlib=libstdc++.
... but if there's only main() then you don't have threads except for the
main thread. Or does LSan crash when trying to access TLS of a main thread?
That's weird anyway. It may be the case that libc++ initializers use TLS
differently than libstdc++ ones.
This seems to be the case… Are there any shared library constructors in
libc++ or libc++abi that aren’t in libstdc++?
(CC’ing Marshall Clow and Eric Fiselier, maybe they can help…)
Information on my system: x86-64, Scientific Linux 6.6 -> glibc 2.12
It seems to work with libc++ on CentOS 7, but then why is libstdc++ also
working on SL6?
I don't know. Is there a difference in what ThreadSelf() and (in
particular) ThreadDescriptorSize() report on these platforms? This code is
really fragile, and it can easily fail for certain versions or forks of
glibc.
ThreadSelf() will report different addresses on each run, both for libc++
and libstdc++.
ThreadDescriptorSize() “correctly” returns 2288 for this 64-bit glibc 2.12
– how can I test if this actually correct on my system?
---
Found the answer myself in this old mail:
Jakub Jelinek - Re: libsanitizer merge from upstream r196090
This reveals: There was a change in size between 2.12.1 and 2.12.2, at
least for 64-bit! (Only problem: RHEL 6 only reports “glibc 2.12” without a
patch level)
I’ve attached a patch that should cover all cases and solves all test
failures for me. If you don’t find it too ugly, I will post it for review…
Cool, thanks for investigation! Yes, please post it for review.