I've tried to create thread-local singleton class with member of std::list
type. During testing my solution with multiple threads, I've encountered strange crash caused by std::list
destructor (more precisely, _M_clear()
method invoked by destructor). It happens even without performing any operations on mentioned list. What is even more strange - this crash ocurrs randomly.
Any ideas, what can be problem here?
Below is minimal example to repreduce this error:
#include <list>
#include <thread>
class tls_list_test
{
private:
std::list<int> test_list;
tls_list_test() = default;
~tls_list_test() = default;
public:
static tls_list_test& get_instance()
{
thread_local tls_list_test instance;
return instance;
}
};
int main()
{
std::list<std::thread> threads;
for (int i = 0; i < 3; ++i)
{
std::thread thread([]()
{
auto& instance = tls_list_test::get_instance();
});
threads.push_back(std::move(thread));
}
for (auto& thread : threads)
{
thread.join();
}
return 0;
}
Code in std::list
causing segfault:
template<typename _Tp, typename _Alloc>
void
_List_base<_Tp, _Alloc>::
_M_clear() _GLIBCXX_NOEXCEPT
{
typedef _List_node<_Tp> _Node;
__detail::_List_node_base* __cur = _M_impl._M_node._M_next;
while (__cur != &_M_impl._M_node)
{
_Node* __tmp = static_cast<_Node*>(__cur);
__cur = __tmp->_M_next; // <- SEGFAULT on this line
_Tp* __val = __tmp->_M_valptr();
#if __cplusplus >= 201103L
_Node_alloc_traits::destroy(_M_get_Node_allocator(), __val);
#else
_Tp_alloc_type(_M_get_Node_allocator()).destroy(__val);
#endif
_M_put_node(__tmp);
}
}
GDB Variables:
Signal = SIGSEGV (Segmentation fault)
__tmp = {std::__cxx11::_List_base<int, std::allocator>::_Node * | 0xfeeefeeefeeefeee} 0xfeeefeeefeeefeee
__val = {int * | 0x2ee4448} 0x2ee4448
this = {std::__cxx11::_List_base<int, std::allocator> * const | 0x2ee5be8} 0x2ee5be8
__cur = {std::__detail::_List_node_base * | 0xfeeefeeefeeefeee} 0xfeeefeeefeeefeee
G++ version:
g++ (x86_64-posix-seh-rev0, Built by MinGW-W64 project) 8.1.0
Aucun commentaire:
Enregistrer un commentaire