[libcxx-dev] Potential issue on ARM32 processors with taking a reference of a newly-inserted map value

Eric Fiselier via libcxx-dev libcxx-dev at lists.llvm.org
Thu Nov 7 04:37:18 PST 2019


On Thu, Nov 7, 2019, 11:16 AM Chris Watts <chris at numbereight.me> wrote:

> There shouldn't be any uninitialized reads here, as State should be
> value-initialized:
>
> If an insertion is performed, the mapped value is value-initialized
>> <https://en.cppreference.com/w/cpp/language/value_initialization> (default-constructed
>> for class types, zero-initialized otherwise) and a reference to it is
>> returned.
>
>
The default constructor which is called does not zero initialize the
members.


> Indeed, this problem also exists if the members of the struct are all
> assigned default values in the definition:
>

To help any further I would need to see a full compilable example which
reproduces the error on your end, and not just code snippets.

have you tried running this code under the ASAN, MSAN, and UBSAN?


> struct State {
>     size_t a = 0;
>     boost::posix_time::ptime b = boost::posix_time::microsec_
> clock::universal_time();
>     bool c = false;
>     bool d = false;
> };
>
> On Thu, 7 Nov 2019 at 00:37, Eric Fiselier <eric at efcs.ca> wrote:
>
>> You're reading from uninitialized memory. That's undefined behavior.
>>
>> On Wed, Nov 6, 2019, 9:17 AM Chris Watts via libcxx-dev <
>> libcxx-dev at lists.llvm.org> wrote:
>>
>>> Hi, I'm new here. Fixed an interesting segfault today. Here's how it
>>> goes.
>>>
>>> I have a std::map of the following struct:
>>>
>>> struct State {
>>>     size_t a;
>>>     boost::posix_time::ptime b;
>>>     bool c;
>>>     bool d;
>>> };
>>> std::map<std::string, State> myMap;
>>>
>>> Then I do a find-or-create operation and take a reference to the result:
>>>
>>> std::string key = arbitraryString();
>>> State& s = myMap[key];
>>>
>>> Now, as long as I only touch the first two members of the struct, all is
>>> rosy.
>>> s.a++;
>>> s.b = boost::posix_time::microsec_clock::universal_time();
>>>
>>> But I found that as soon as I touched `s.c` or `s.d`, a segfault occurs
>>> at `State& s = myMap[key];`:
>>>
>>> if (!s.c) { ... // Eventually causes a segfault at the assignment of s.
>>> Before the segfault, the value of s.c is often random data and not the
>>> expected value.
>>>
>>> While this segfault is spurious, it is frequent enough to reproduce
>>> reliably.
>>> Unfortunately, this may be impractical to reproduce for many of you as
>>> it only crashed on two of our armv7 hosts: a Motorola G6, and a Samsung J6.
>>> arm64 hosts appear to be unaffected.
>>>
>>> My suspicion is that a temporary struct is being created with
>>> `myMap[key]`, and the reference of that is being returned before it is
>>> added to the map, but the memory is invalidated shortly after.
>>>
>>> It could be related to caching/register optimization, as the issue
>>> doesn't happen if `State::c` and `State::d` are declared before `
>>> State::a`.
>>>
>>> The issue doesn't occur in `std::unordered_map`.
>>>
>>> Clang details:
>>> Android (5220042 based on r346389c) clang version 8.0.7 (
>>> https://android.googlesource.com/toolchain/clang
>>> b55f2d4ebfd35bf643d27dbca1bb228957008617) (
>>> https://android.googlesource.com/toolchain/llvm
>>> 3c393fe7a7e13b0fba4ac75a01aa683d7a5b11cd) (based on LLVM 8.0.7svn)
>>> Target: armv7a-unknown-linux-android29
>>> Thread model: posix
>>>
>>> libc++ details:
>>> Actually I really don't know how to get this. Help:
>>> ndk-bundle/toolchains/llvm/prebuilt/linux-x86_64/bin/arm-linux-androideabi-readelf
>>> -a ./ndk-bundle/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a/libc++.so.28
>>> readelf: Error:
>>> ./ndk-bundle/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a/libc++.so.28:
>>> Failed to read file header
>>>
>>> Is anyone able to confirm? What more information do I need to collect?
>>> _______________________________________________
>>> libcxx-dev mailing list
>>> libcxx-dev at lists.llvm.org
>>> https://lists.llvm.org/cgi-bin/mailman/listinfo/libcxx-dev
>>>
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/libcxx-dev/attachments/20191107/c82d5ee7/attachment.html>


More information about the libcxx-dev mailing list