Hello! I just added code to setup the “last will and testament” with Mosquitto MQTT (C interface, Ubuntu Linux on x86-64).
If I call mosquitto_will_set_v5() with “null” for the properties, everything works fine. If I setup properties and pass them into mosquitto_will_set_v5(), I crash when the client tries to connect.
Here is the code snippet:
// Setup properties
mosquitto_property *proplist = NULL;
int mosqErr = 0;
#if 1
// XXXXX These cause a crash during the connection phase
mosqErr |= mosquitto_property_add_string(&proplist, MQTT_PROP_CONTENT_TYPE, METADATA_CONTENT_TYPE_APP_JSON);
mosqErr |= mosquitto_property_add_int32(&proplist, MQTT_PROP_WILL_DELAY_INTERVAL, LWT_DELAY_S);
#endif
if(HSM_OK != err)
{
NS_LOG_ERROR(“HsmUtils_MakeHubId() returned %d!”, err);
return err;
}
// Setup the LWT
mosqErr = mosquitto_will_set_v5(cloudComsAppInst.mosq, TOPIC_CLOUD_LAST_WILL_TESTAMENT,
strlen(lwtJsonStr)+1, lwtJsonStr, MQTT_QOS, LWT_RETAIN, proplist);
if(0 != mosqErr)
{
NS_LOG_ERROR("mosquitto_will_set_v5() return %d, \"%s\"", mosqErr, mosquitto_strerror(mosqErr));
err = HSM_ERR_MQTT_LWT;
}
And:
#define TOPIC_CLOUD_LAST_WILL_TESTAMENT “d2c/will” ///< Last Will and Testament
#define LWT_RETAIN false
#define LWT_DELAY_S 5
…
Call stack:
Can anyone give some guidance here? Anyone else using mosquitto_will_set_v5() with properties?
Thanks
Hi,
I’ve tried with this example on Ubuntu 24.04 and it works as expected. Could you try it and see if it is ok, then find the differences compared to what you have?
Regards,
Roger
#include <mosquitto.h>
#include <mqtt_protocol.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <mosquitto.h>
#include <mqtt_protocol.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
void on_connect(struct mosquitto *mosq, void *userdata, int rc)
{
printf("%s\n", mosquitto_connack_string(rc));
}
int main(int argc, char *argv[])
{
struct mosquitto *mosq;
int rc;
mosquitto_lib_init();
mosq = mosquitto_new(NULL, true, NULL);
if(mosq == NULL){
fprintf(stderr, "Error: Out of memory.\n");
return 1;
}
mosquitto_connect_callback_set(mosq, on_connect);
mosquitto_int_option(mosq, MOSQ_OPT_PROTOCOL_VERSION, 5);
mosquitto_property *proplist = NULL;
rc = mosquitto_property_add_string(&proplist, MQTT_PROP_CONTENT_TYPE, "application/json");
if(rc){
fprintf(stderr, "mosquitto_property_add_string failed: %s\n", mosquitto_strerror(rc));
mosquitto_destroy(mosq);
return 1;
}
mosquitto_property_add_int32(&proplist, MQTT_PROP_WILL_DELAY_INTERVAL, 60);
if(rc){
fprintf(stderr, "mosquitto_property_add_int32 failed: %s\n", mosquitto_strerror(rc));
mosquitto_destroy(mosq);
return 1;
}
mosquitto_will_set_v5(mosq, "will-topic", strlen("payload"), "payload", 0, 0, proplist);
rc = mosquitto_connect(mosq, "test.mosquitto.org", 1883, 60);
if(rc != MOSQ_ERR_SUCCESS){
mosquitto_destroy(mosq);
fprintf(stderr, "Error: %s\n", mosquitto_strerror(rc));
return 1;
}
mosquitto_loop_forever(mosq, -1, 1);
mosquitto_lib_cleanup();
return 0;
}
@roger.light thanks for looking into this. I ran your example as-is and it works fine on my setup. Further, I did my best to make my code look as much like yours as possible, but I’m still getting crashes.
Interestingly. I commented-out some big chunks of code (there are several threads running concurrently doing all sorts of things) and the location of the crash moved. This implies a stack overflow or some other memory corruption that may or may not be related to the code at hand.
I will keep looking and report back. Thanks again.
I found the root cause. It was actually a pretty straight-forward error in usage.
I was calling mosquitto_property_free_all() after my call to mosquitto_will_set_v5(). Later, when the connect executed, it was trying to read the properties that had been freed.
I had assumed (falsely) that the properties were “deep” copied in mosquitto_will_set_v5(), but that’s not true.
Simply removing the call to mosquitto_property_free_all() fixed the problem. If this is not correct or sufficient (i.e. is there a memory leak I just caused?), please let me know.
Thanks for your help!