Description
Issue Description
When automatic reconnection is enabled in the MQTT client, manually calling client.reconnect()
after a disconnect causes the application to crash. This issue occurs specifically when the client doesn't automatically reconnect after a manual disconnect. Disabling automatic reconnection prevents this crash.
Steps to Reproduce
- Enable automatic reconnection in the MQTT client.
auto connOpts = mqtt::connect_options_builder()
.clean_session(false)
.automatic_reconnect(seconds(2), seconds(30))
.finalize();
- Manually disconnect the client.
cli->disconnect()->wait();
- Attempt to manually reconnect using
client.reconnect()
.
cli->reconnect()->wait();
Expected Behavior
The client should successfully reconnect without causing the application to crash, regardless of whether automatic reconnection is enabled or not.
Actual Behavior
The application crashes when client.reconnect()
is called with automatic reconnection enabled. Backtrace from a modified multithr_pub_sub.cpp
:
0x0000007ff7b1b7e8 in raise () from /lib/libc.so.6
(gdb) bt
#0 0x0000007ff7b1b7e8 in raise () from /lib/libc.so.6
#1 0x0000007ff7b08dd4 in abort () from /lib/libc.so.6
#2 0x0000007ff7dc0cf8 in __gnu_cxx::__verbose_terminate_handler() () from /usr/lib/libstdc++.so.6
#3 0x0000007ff7dbe85c in ?? () from /usr/lib/libstdc++.so.6
#4 0x0000007ff7dbe8c0 in std::terminate() () from /usr/lib/libstdc++.so.6
#5 0x0000007ff7dbebb0 in __cxa_throw () from /usr/lib/libstdc++.so.6
#6 0x00000000004127c0 in mqtt::async_client::reconnect() ()
#7 0x0000000000406210 in publisher_func(std::shared_ptr<mqtt::async_client>, std::shared_ptr<multithr_counter>) ()
#8 0x000000000040f288 in void std::__invoke_impl<void, void (*)(std::shared_ptr<mqtt::async_client>, std::shared_ptr<multithr_counter>), std::shared_ptr<mqtt::async_client>, std::shared_ptr<multithr_counter> >(std::__invoke_other, void (*&&)(std::shared_ptr<mqtt::async_client>, std::shared_ptr<multithr_counter>), std::shared_ptr<mqtt::async_client>&&, std::shared_ptr<multithr_counter>&&) ()
#9 0x000000000040f174 in std::__invoke_result<void (*)(std::shared_ptr<mqtt::async_client>, std::shared_ptr<multithr_counter>), std::shared_ptr<mqtt::async_client>, std::shared_ptr<multithr_counter> >::type std::__invoke<void (*)(std::shared_ptr<mqtt::async_client>, std::shared_ptr<multithr_counter>), std::shared_ptr<mqtt::async_client>, std::shared_ptr<multithr_counter> >(void (*&&)(std::shared_ptr<mqtt::async_client>, std::shared_ptr<multithr_counter>), std::shared_ptr<mqtt::async_client>&&, std::shared_ptr<multithr_counter>&&) ()
#10 0x000000000040f10c in void std::thread::_Invoker<std::tuple<void (*)(std::shared_ptr<mqtt::async_client>, std::shared_ptr<multithr_counter>), std::shared_ptr<mqtt::async_client>, std::shared_ptr<multithr_counter> > >::_M_invoke<0ul, 1ul, 2ul>(std::_Index_tuple<0ul, 1ul, 2ul>) ()
#11 0x000000000040f098 in std::thread::_Invoker<std::tuple<void (*)(std::shared_ptr<mqtt::async_client>, std::shared_ptr<multithr_counter>), std::shared_ptr<mqtt::async_client>, std::shared_ptr<multithr_counter> > >::operator()() ()
#12 0x000000000040ec58 in std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)(std::shared_ptr<mqtt::async_client>, std::shared_ptr<multithr_counter>), std::shared_ptr<mqtt::async_client>, std::shared_ptr<multithr_counter> > > >::_M_run() ()
#13 0x0000007ff7de9eec in ?? () from /usr/lib/libstdc++.so.6
#14 0x0000007ff7fa5478 in ?? () from /lib/libpthread.so.0
#15 0x0000007ff7bb4c1c in ?? () from /lib/libc.so.6
Additional Context
I have a callback for when the network is disconnected, and then reconnected. If I don't force the MQTT client to disconnect, it will never update to think it is disconnected, and therefore never retry connecting. As a result, I want to make sure that I do reconnect. I was hoping to avoid re-instantiating all of my options again with a standard client->connect()
but if that is the suggested/correct approach, I can do that.