Describe the bug
Deleting AsyncRedisCluster caused core dump if want to use different host/ip configure when redis-server cluster nodes scale in/out.
To Reproduce
[1.] Create async redis cluster with initial ip resolved from fqdn host in following way.
this->client = new AsyncRedisCluster(cops, poolOption);
[2.] Continue the traffic
[3.] scale in or scale out existing redis server master/slave nodes.(kill -9 redis-server-pid and restart new one or execute kubernetes scale in/out for the redis pods) .
kubectl scale sts rtdb --replicas=18
kubectl scale sts rtdb --replicas 0
kubectl scale sts rtdb --replicas=18
[4.] stop traffic when detecting redis server cluster is not health
[5.] keep cluster audit every 2 seconds by sending "cluster info".
[6.] After audit failure up to threshold number(3), delete existing AsyncRedisCluster and create new one with new ip configure during the redis server cluster nodes changed. The same thread is used to send cluster audit and destroy existing AsyncRedisCluster.
[7.] coredump fired when deleting AsyncRedisCluster
coredump example 1:
(gdb) bt
#0 0xf7ee6129 in __kernel_vsyscall ()
#1 0xf56fcad6 in raise () from /lib/libc.so.6
#2 0xf56e2f12 in abort () from /lib/libc.so.6
#3 0xf59d3f81 in __gnu_cxx::__verbose_terminate_handler() [clone .cold.1] () from /lib/libstdc++.so.6
#4 0xf59dbb08 in __cxxabiv1::__terminate(void ()()) () from /lib/libstdc++.so.6
#5 0xf59da85b in __cxa_call_terminate () from /lib/libstdc++.so.6
#6 0xf59db31a in __gxx_personality_v0 () from /lib/libstdc++.so.6
#7 0xf5886e76 in _Unwind_RaiseException_Phase2 () from /lib/libgcc_s.so.1
#8 0xf58872c3 in _Unwind_RaiseException () from /lib/libgcc_s.so.1
#9 0xf59dbe93 in __cxa_throw () from /lib/libstdc++.so.6
#10 0xf59d6947 in std::__throw_system_error(int) [clone .cold.28] () from /lib/libstdc++.so.6
#11 0xf5a0b0ca in std::thread::join() () from /lib/libstdc++.so.6
#12 0xf54474a3 in sw::redis::AsyncShardsPool::~AsyncShardsPool() () from /lib/libredis++.so.1
#13 0xf5446ed0 in void __gnu_cxx::new_allocatorsw::redis::AsyncShardsPool::destroysw::redis::AsyncShardsPool(sw::redis::AsyncShardsPool) () from /lib/libredis++.so.1
#14 0xf5446e5d in void std::allocator_traits<std::allocatorsw::redis::AsyncShardsPool >::destroysw::redis::AsyncShardsPool(std::allocatorsw::redis::AsyncShardsPool&, sw::redis::AsyncShardsPool*) () from /lib/libredis++.so.1
coredump example 2:
(gdb) bt
#0 0xf7f30129 in __kernel_vsyscall ()
#1 0xf57cbad6 in raise () from /lib/libc.so.6
#2 0xf57b1f12 in abort () from /lib/libc.so.6
#3 0xf5aa2f81 in __gnu_cxx::__verbose_terminate_handler() [clone .cold.1] () from /lib/libstdc++.so.6
#4 0xf5aaab08 in __cxxabiv1::__terminate(void ()()) () from /lib/libstdc++.so.6
#5 0xf5aa985b in __cxa_call_terminate () from /lib/libstdc++.so.6
#6 0xf5aaa31a in __gxx_personality_v0 () from /lib/libstdc++.so.6
#7 0xf5955e76 in _Unwind_RaiseException_Phase2 () from /lib/libgcc_s.so.1
#8 0xf59562c3 in _Unwind_RaiseException () from /lib/libgcc_s.so.1
#9 0xf5aaae93 in __cxa_throw () from /lib/libstdc++.so.6
#10 0xf5aa5947 in std::__throw_system_error(int) [clone .cold.28] () from /lib/libstdc++.so.6
#11 0xf5ada0ca in std::thread::join() () from /lib/libstdc++.so.6
#12 0xf5507916 in std::_Sp_ebo_helper<0, std::allocatorsw::redis::EventLoop, true>::_Sp_ebo_helper(std::allocatorsw::redis::EventLoop const&) () from /lib/libredis++.so.1
#13 0xf5507815 in void std::allocator_traits<std::allocatorsw::redis::AsyncConnectionPool >::construct<sw::redis::AsyncConnectionPool, sw::redis::SimpleAsyncSentinel, std::shared_ptrsw::redis::EventLoop&, sw::redis::ConnectionPoolOptions const&, sw::redis::ConnectionOptions const&>(std::allocatorsw::redis::AsyncConnectionPool&, sw::redis::AsyncConnectionPool, sw::redis::SimpleAsyncSentinel&&, std::shared_ptrsw::redis::EventLoop&, sw::redis::ConnectionPoolOptions const&, sw::redis::ConnectionOptions const&) ()
from /lib/libredis++.so.1
#14 0xf5506fae in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count<sw::redis::AsyncConnectionPool, std::allocatorsw::redis::AsyncConnectionPool, std::shared_ptrsw::redis::EventLoop&, sw::redis::ConnectionPoolOptions const&, sw::redis::ConnectionOptions const&>(sw::redis::AsyncConnectionPool*&, std::_Sp_alloc_shared_tag<std::allocatorsw::redis::AsyncConnectionPool >, std::shared_ptrsw::redis::EventLoop&, sw::redis::ConnectionPoolOptions const&, sw::redis::ConnectionOptions const&) () from /lib/libredis++.so.1
#15 0xf5506f75 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count<sw::redis::AsyncConnectionPool, std::allocatorsw::redis::AsyncConnectionPool, std::shared_ptrsw::redis::EventLoop&, sw::redis::ConnectionPoolOptions const&, sw::redis::ConnectionOptions const&>(sw::redis::AsyncConnectionPool*&, std::_Sp_alloc_shared_tag<std::allocatorsw::redis::AsyncConnectionPool >, std::shared_ptrsw::redis::EventLoop&, sw::redis::ConnectionPoolOptions const&, sw::redis::ConnectionOptions const&) () from /lib/libredis++.so.1
#16 0xf5506e42 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count<sw::redis::AsyncConnectionPool, std::allocatorsw::redis::AsyncConnectionPool, std::shared_ptrsw::redis::EventLoop&, sw::redis::ConnectionPoolOptions const&, sw::redis::ConnectionOptions const&>(sw::redis::AsyncConnectionPool*&, std::_Sp_alloc_shared_tag<std::allocatorsw::redis::AsyncConnectionPool >, std::shared_ptrsw::redis::EventLoop&, sw::redis::ConnectionPoolOptions const&, sw::redis::ConnectionOptions const&) () from /lib/libredis++.so.1
--Type for more, q to quit, c to continue without paging--
Expected behavior
No crash when deleting AsyncRedisCluster.
Environment:
OS: Rocky Linux 8.2-20.el8.0.1
Compiler: gcc version 8.5.0
hiredis version: hiredis 1.2.0
redis-plus-plus version: 1.3.14
Additional context
Redis cluster is used with 9 masters and 9 slaves.
Describe the bug
Deleting AsyncRedisCluster caused core dump if want to use different host/ip configure when redis-server cluster nodes scale in/out.
To Reproduce
[1.] Create async redis cluster with initial ip resolved from fqdn host in following way.
this->client = new AsyncRedisCluster(cops, poolOption);
[2.] Continue the traffic
[3.] scale in or scale out existing redis server master/slave nodes.(kill -9 redis-server-pid and restart new one or execute kubernetes scale in/out for the redis pods) .
kubectl scale sts rtdb --replicas=18
kubectl scale sts rtdb --replicas 0
kubectl scale sts rtdb --replicas=18
[4.] stop traffic when detecting redis server cluster is not health
[5.] keep cluster audit every 2 seconds by sending "cluster info".
[6.] After audit failure up to threshold number(3), delete existing AsyncRedisCluster and create new one with new ip configure during the redis server cluster nodes changed. The same thread is used to send cluster audit and destroy existing AsyncRedisCluster.
[7.] coredump fired when deleting AsyncRedisCluster
coredump example 1:
(gdb) bt
#0 0xf7ee6129 in __kernel_vsyscall ()
#1 0xf56fcad6 in raise () from /lib/libc.so.6
#2 0xf56e2f12 in abort () from /lib/libc.so.6
#3 0xf59d3f81 in __gnu_cxx::__verbose_terminate_handler() [clone .cold.1] () from /lib/libstdc++.so.6
#4 0xf59dbb08 in __cxxabiv1::__terminate(void ()()) () from /lib/libstdc++.so.6
#5 0xf59da85b in __cxa_call_terminate () from /lib/libstdc++.so.6
#6 0xf59db31a in __gxx_personality_v0 () from /lib/libstdc++.so.6
#7 0xf5886e76 in _Unwind_RaiseException_Phase2 () from /lib/libgcc_s.so.1
#8 0xf58872c3 in _Unwind_RaiseException () from /lib/libgcc_s.so.1
#9 0xf59dbe93 in __cxa_throw () from /lib/libstdc++.so.6
#10 0xf59d6947 in std::__throw_system_error(int) [clone .cold.28] () from /lib/libstdc++.so.6
#11 0xf5a0b0ca in std::thread::join() () from /lib/libstdc++.so.6
#12 0xf54474a3 in sw::redis::AsyncShardsPool::~AsyncShardsPool() () from /lib/libredis++.so.1
#13 0xf5446ed0 in void __gnu_cxx::new_allocatorsw::redis::AsyncShardsPool::destroysw::redis::AsyncShardsPool(sw::redis::AsyncShardsPool) () from /lib/libredis++.so.1
#14 0xf5446e5d in void std::allocator_traits<std::allocatorsw::redis::AsyncShardsPool >::destroysw::redis::AsyncShardsPool(std::allocatorsw::redis::AsyncShardsPool&, sw::redis::AsyncShardsPool*) () from /lib/libredis++.so.1
coredump example 2:
(gdb) bt
#0 0xf7f30129 in __kernel_vsyscall ()
#1 0xf57cbad6 in raise () from /lib/libc.so.6
#2 0xf57b1f12 in abort () from /lib/libc.so.6
#3 0xf5aa2f81 in __gnu_cxx::__verbose_terminate_handler() [clone .cold.1] () from /lib/libstdc++.so.6
#4 0xf5aaab08 in __cxxabiv1::__terminate(void ()()) () from /lib/libstdc++.so.6
#5 0xf5aa985b in __cxa_call_terminate () from /lib/libstdc++.so.6
#6 0xf5aaa31a in __gxx_personality_v0 () from /lib/libstdc++.so.6
#7 0xf5955e76 in _Unwind_RaiseException_Phase2 () from /lib/libgcc_s.so.1
#8 0xf59562c3 in _Unwind_RaiseException () from /lib/libgcc_s.so.1
#9 0xf5aaae93 in __cxa_throw () from /lib/libstdc++.so.6
#10 0xf5aa5947 in std::__throw_system_error(int) [clone .cold.28] () from /lib/libstdc++.so.6
#11 0xf5ada0ca in std::thread::join() () from /lib/libstdc++.so.6
#12 0xf5507916 in std::_Sp_ebo_helper<0, std::allocatorsw::redis::EventLoop, true>::_Sp_ebo_helper(std::allocatorsw::redis::EventLoop const&) () from /lib/libredis++.so.1
#13 0xf5507815 in void std::allocator_traits<std::allocatorsw::redis::AsyncConnectionPool >::construct<sw::redis::AsyncConnectionPool, sw::redis::SimpleAsyncSentinel, std::shared_ptrsw::redis::EventLoop&, sw::redis::ConnectionPoolOptions const&, sw::redis::ConnectionOptions const&>(std::allocatorsw::redis::AsyncConnectionPool&, sw::redis::AsyncConnectionPool, sw::redis::SimpleAsyncSentinel&&, std::shared_ptrsw::redis::EventLoop&, sw::redis::ConnectionPoolOptions const&, sw::redis::ConnectionOptions const&) ()
from /lib/libredis++.so.1
#14 0xf5506fae in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count<sw::redis::AsyncConnectionPool, std::allocatorsw::redis::AsyncConnectionPool, std::shared_ptrsw::redis::EventLoop&, sw::redis::ConnectionPoolOptions const&, sw::redis::ConnectionOptions const&>(sw::redis::AsyncConnectionPool*&, std::_Sp_alloc_shared_tag<std::allocatorsw::redis::AsyncConnectionPool >, std::shared_ptrsw::redis::EventLoop&, sw::redis::ConnectionPoolOptions const&, sw::redis::ConnectionOptions const&) () from /lib/libredis++.so.1
#15 0xf5506f75 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count<sw::redis::AsyncConnectionPool, std::allocatorsw::redis::AsyncConnectionPool, std::shared_ptrsw::redis::EventLoop&, sw::redis::ConnectionPoolOptions const&, sw::redis::ConnectionOptions const&>(sw::redis::AsyncConnectionPool*&, std::_Sp_alloc_shared_tag<std::allocatorsw::redis::AsyncConnectionPool >, std::shared_ptrsw::redis::EventLoop&, sw::redis::ConnectionPoolOptions const&, sw::redis::ConnectionOptions const&) () from /lib/libredis++.so.1
#16 0xf5506e42 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count<sw::redis::AsyncConnectionPool, std::allocatorsw::redis::AsyncConnectionPool, std::shared_ptrsw::redis::EventLoop&, sw::redis::ConnectionPoolOptions const&, sw::redis::ConnectionOptions const&>(sw::redis::AsyncConnectionPool*&, std::_Sp_alloc_shared_tag<std::allocatorsw::redis::AsyncConnectionPool >, std::shared_ptrsw::redis::EventLoop&, sw::redis::ConnectionPoolOptions const&, sw::redis::ConnectionOptions const&) () from /lib/libredis++.so.1
--Type for more, q to quit, c to continue without paging--
Expected behavior
No crash when deleting AsyncRedisCluster.
Environment:
OS: Rocky Linux 8.2-20.el8.0.1
Compiler: gcc version 8.5.0
hiredis version: hiredis 1.2.0
redis-plus-plus version: 1.3.14
Additional context
Redis cluster is used with 9 masters and 9 slaves.