Open smallSwed opened 6 months ago
Thanks for the investigation.
There's no MQTTAsync_disconnect call showing in this log - there's an internal call. If you did call MQTTAsync_disconnect I would expect it to return "not connected" as does MQTTAsync_send once the connection is lost. Then there would be no success or failure callback.
I've put in a simple fix for the memory leak. I think there might be a case I'm missing with this, but the CI tests pass, and I haven't found any other problem yet.
I've recently increased the synchronization of API calls in the library, so this may rule out the circumstances which cause the disconnect call to be processed. I've not seen this myself in any testing I've done so far.
Both these changes are in the develop branch.
Describe the bug I have a publisher publishing messages via MQTTAsync_sendMessage. If I initiate a shutdown but the connection was already lost to the broker, the MqttAsync_disconnect returns Success but never processed: no callback called (neither failure nor success) My disconnect wait will timeout. So I call the MqttAsync_destroy which will leak.
To Reproduce Not always reproducible, needs certain conditions met: it needs some
PUBLISH
commands in theMQTTAsync_commands
when the connection is lost:Expected behavior A proper cleanup for unsent but queued publish messages maybe: MqttAsync_disconnect would disconnect no matter if there are queued publish commands
Log files memory_leak.log
Points of interest in the log file:
I had to clean the log files from some of the logs of my application, but all of the PAHO logs are included in the file.
Environment (please complete the following information):
Additional context One condition for this bug is the lost connection to the broker and no reconnect in a reasonable time.
The leaked data is the payload and the destination name string passed to
MQTTAsync_sendMessage
for all unsent messages.I did some investigation and it's comes down to this:
MqttAsync_disconnect
call will put aDISCONNECT
command at the end ofMQTTAsync_commands
MQTTAsync_processCommand
will find aPUBLISH
command for our client which is disconnected so it will be not processed and always stays at the start of the list. Our client will be put inside theignore_clients
so theDISCONNECT
will be ignored at the end of the list.MQTTAsync_destroy
there is an assumption that all thepayload
s anddestinationName
s are stored inMQTTProtocol_storePublication
so theMQTTAsync_NULLPublishCommands
called , but for some reason those are not stored there or not freed from there.The leaked
malloc
s are fromMQTTAsync_send
:The call stack: