带有thread_local和std :: unordered_map的Segfault

时间:2017-12-07 00:36:22

标签: c++ macos c++11 thread-safety

在调试会话期间,我发现了一个问题,我能够减少到这个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;
}

我使用的编译器是g++-6 (Homebrew GCC 6.4.0) 6.4.0上的MacOS 10.12.6。 问题是它似乎在member的析构函数内崩溃。

但它并不总是崩溃,这让我想知道它是否是线程之间的某种竞争条件。

感谢任何帮助,这让我感到疯狂。

我在Windows上与MinGW有类似的崩溃,所以我真的希望从了解这里发生的事情的人那里获得一些知识。

这是此代码中更激烈的崩溃日志之一:

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

0 个答案:

没有答案