Segfault with thread_local and std :: unordered_map

During a debugging session, I discovered a problem that I was able to compile this code in C ++ 11:

#include <thread>
#include <vector>
#include <unordered_map>

class MyClass
{
    public:
        MyClass(){
            printf("%p\n", this);
        }
        ~MyClass(){
            printf("~%p\n", this);
        }

        std::unordered_map<int, int> member;
};

thread_local MyClass threadLocalObject;

int main(){
    std::vector<std::thread> threads;

    for (int i = 0; i < 40; ++i){
        threads.emplace_back([&](){
            printf("%ld\n", threadLocalObject.member.size());
        });
    }

    for (auto &thread : threads)
        thread.join();

    return 0;
}

The compiler is used g++-6 (Homebrew GCC 6.4.0) 6.4.0on MacOS 10.12.6. The problem is that it seems to crash inside the destructor member.

However, this does not always lead to a failure, which makes me wonder if this is some kind of race condition between threads.

Any help is appreciated, it drives me crazy.

I had similar crashes with MinGW on Windows, so I really hope to get some knowledge from those who understand what is going on here.

This is one of the sharpest crashlogs of this code:

0x7f9b2ba00228
0x7f9b2ac02728
0x7f9b2ba004e8
0x7f9b2ae00128
0x7f9b2b800128
0x7f9b2ad00128
0x7f9b2ac025f8
0x7f9b2ad00178
0x7f9b2b900138
0x7f9b2b800288
0x7f9b2ad002d8
0x7f9b2b900188
0x7f9b2ba00388
0x7f9b2b800548
0x7f9b2b8003e8
0x7f9b2b800cd8
0x7f9b2af00898
0x7f9b2ba00a68
0x7f9b2ae00ad8
0x7f9b2af00c08
0x7f9b2b900918
0x7f9b2ba00dd8
0x7f9b2b801048
0x7f9b2ae00e48
0x7f9b2b8013b8
0x7f9b2b801728
0x7f9b2af00f78
0x7f9b2ba00538
0x7f9b2af012e8
0x7f9b2b9002e8
0x7f9b2af00268
0x7f9b2ae004a8
0x7f9b2b900338
0x7f9b2af003c8
0x7f9b2ae00608
0x7f9b2af00528
0x7f9b2ae00768
0x7f9b2ae008c8
0x7f9b2af00688
0x7f9b2af006d8
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
~0x7f9b2ba00228
0
0
0
0
0
0
0
0
0
0
0
0
~0x7f9b2ac025f8
~0x7f9b2ad00178
~0x7f9b2ad00128
a.out(32726,0x70000e123000) malloc: *** error for object 0xa38333130303962: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
~0x7f9b2b900138
~0x7f9b2ad002d8
a.out(32726,0x70000e2ac000) malloc: *** error for object 0xa38633830306561: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
~0x7f9b2ba00388
~0x7f9b2b800288
~0x7f9b2b800548
~0x7f9b2b8003e8
~0x7f9b2b800cd8
~0x7f9b2af00898
~0x7f9b2ba00a68
~0x7f9b2ae00ad8
~0x7f9b2af00c08
~0x7f9b2b900918
~0x7f9b2ba00dd8
~0x7f9b2ae00e48
~0x7f9b2b801048
~0x7f9b2b8013b8
~0x7f9b2b801728
~0x7f9b2af00f78
~0x7f9b2ba00538
~0x7f9b2af012e8
~0x7f9b2b9002e8
~0x7f9b2ae004a8
~0x7f9b2af00268
~0x7f9b2b900338
~0x7f9b2af003c8
~0x7f9b2ae00608
~0x7f9b2af00528
~0x7f9b2ae00768
~0x7f9b2ae008c8
~0x7f9b2af00688
~0x7f9b2af006d8
~0x7f9b2ac02728
~0x7f9b2ae00128
~0x7f9b2b800128
Illegal instruction: 4
+4
source share

Source: https://habr.com/ru/post/1690357/


All Articles