Subject: Re: [Boost-bugs] [Boost C++ Libraries] #11968: Undefined behavior in `boost::lockfree::queue`: nodes are always misaligned
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2016-08-09 09:43:02
#11968: Undefined behavior in `boost::lockfree::queue`: nodes are always misaligned
--------------------------------------+--------------------------
Reporter: yury.zaytsev@⦠| Owner: timblechmann
Type: Bugs | Status: new
Milestone: To Be Determined | Component: lockfree
Version: Boost Development Trunk | Severity: Showstopper
Resolution: | Keywords:
--------------------------------------+--------------------------
Comment (by yury.zaytsev@â¦):
Hi Tim,
This is to let you know that the problem is actually much more serious
than I've originally thought: as it turns out, the unfortunate interaction
of this bug with atomic libcall emission strategy in clang++-3.8 causes
the latter to generate libcalls to `libatomic` for accesses to the
lockfree queues, which is annoying (you have to manually link against
`libatomic`) and might possibly lead to crashes in combination with other
voodoo.
I was able to reproduce libcall emission in the minimal example above, but
not the crashes, however, I've seen the crashes in our production code.
They might be caused by the interplay of the general insanity of our code
with this particular problem, but if it crashes for us, then it can
possibly crash for others.
Anyways, my understanding is that as clang sees that your nodes can't
possibly be correctly aligned as requested, it errs at the side of caution
and generates libcalls to `libatomic` functions (i.e. `__atomic_store_4`,
etc.) instead sticking to the atomic ops on x86, even though the latter
would still work, only with a performance penalty, unlike on some other
arches such as ARM.
Contrarily to this clang-3.8 behavior, gcc 6.1 generates atomic ops in
this case, probably because it knows that they would still work on x86, or
maybe I'm overestimating its intelligence and it simply doesn't care, but
anyhow our code works just fine.
If you want to reproduce it, then compile the minimal example above with
gcc & clang against Boost 1.61 and search for (1) libcalls
(`__atomic_...`) and (2) atomic ops (`lock ...`):
{{{
{g++-6,clang++-3.8} -S -o lockfree.asm -std=c++14 -O3 -march=native
lockfree.cpp
}}}
Now, the funny thing is that I've discovered that accidentally the
following commit fixes the issue for me:
https://github.com/boostorg/lockfree/commit/72548c26e5243c88660e8c24524616dff3f18164
Unfortunately, it seems that it's only going to make it in Boost 1.62.
However, I have discovered a workaround for Boost 1.61: if one forces the
use of Boost.Atomic instead of `std::atomic`, then `clang++-3.8` doesn't
emit the libcalls anymore and sticks to the atomic ops!
P.S. The moral of this story: check your code with anything you might get
your hands on (tests, various compilers, static analyzers, instrumentation
systems, etc.) and don't ignore the problems that they are reporting!
Hope that helps,
--Yury.
-- Ticket URL: <https://svn.boost.org/trac/boost/ticket/11968#comment:2> Boost C++ Libraries <http://www.boost.org/> Boost provides free peer-reviewed portable C++ source libraries.
This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:20 UTC