Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A segment error occurred after the conn_lost() was executed #1507

Open
okyihu opened this issue Aug 14, 2024 · 2 comments
Open

A segment error occurred after the conn_lost() was executed #1507

okyihu opened this issue Aug 14, 2024 · 2 comments
Labels

Comments

@okyihu
Copy link

okyihu commented Aug 14, 2024

HI,SIR
A segment fault occurred after the conn_lost() was executed ,
once I called MQTTClient_connect(client, &conn_opts) in conn_lost() function , the programe could re-connect the broker, but immediately a segment fault occured , why, what am I doing wrong.
more information : just now I re-compile this program with gcc and run it on unbuntu desktop system , this program run correctly ,no segment fault . so strange.

My code is :
#include "stdlib.h"
#include "string.h"
#include "unistd.h"
#include "MQTTClient.h"
#include "mqtt_req_proc.h"

// Enable or disable SSL/TLS connection (1 for SSL/TLS, 0 for TCP)
#define USE_SSL 0

#if USE_SSL
#define ADDRESS "ssl://broker.emqx.io:8883"
#else
// #define ADDRESS "tcp://47.106.203.236:1883"
#define ADDRESS "tcp://112.74.85.63:1883"
// #define ADDRESS "b187a1e0.ala.dedicated.aliyun.emqxcloud.cn:1883"
#endif

#define USERNAME "steve"
#define PASSWORD "Zrr_4410693"
#define CLIENTID "c-client"
#define QOS 0
#define PUB_TOPIC "192.168.1.103_internal_service"
#define SUB_TOPIC "192.168.1.103_public_service"
#define TIMEOUT 10000L

MQTTClient_SSLOptions configureSSLOptions()
{
MQTTClient_SSLOptions ssl_opts = MQTTClient_SSLOptions_initializer;
ssl_opts.enableServerCertAuth = 1;
// ssl_opts.trustStore = CA_CERTIFICATE_FILE;
return ssl_opts;
}

void publish(MQTTClient client, char *topic, char *payload)
{
MQTTClient_message message = MQTTClient_message_initializer;
message.payload = payload;
message.payloadlen = strlen(payload);
message.qos = QOS;
message.retained = 1;
MQTTClient_deliveryToken token;
MQTTClient_publishMessage(client, topic, &message, &token);
MQTTClient_waitForCompletion(client, token, TIMEOUT);
printf("Send %s to topic %s \n", payload, PUB_TOPIC);
}
int request_completed = 0;
int on_message(void *context, char *topicName, int topicLen, MQTTClient_message *message)
{
char *payload = message->payload;
// printf("Received %s from %s topic \n", payload, topicName);

    request_completed = 1;
    MQTTClient_freeMessage(&message);
    MQTTClient_free(topicName);
    return 1;

}

void conn_lost(void *context, char *cause)
{
printf("\nConnection lost\n");
printf(" cause: %s\n", cause);
int rc;
MQTTClient client = (MQTTClient )context;

MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
     conn_opts.username = USERNAME;
    conn_opts.password = PASSWORD;
conn_opts.keepAliveInterval = 10;
conn_opts.cleansession = 1;

while (1)
{
            rc= MQTTClient_connect(client, &conn_opts);
	if (rc == MQTTCLIENT_SUCCESS)
	{
		printf("Reconnection Successful\n");
		break;
	}
	else
	{
		printf("Failed to connect, return code %d\n", rc);
	}
	sleep(10);
}

while (1)
{
	if (MQTTClient_subscribe(client, SUB_TOPIC, QOS) == MQTTCLIENT_SUCCESS)
	{
		printf("Resubscribe Successful\n");
		break;
	}
	else
	{
		printf("Resubscribe Failure\n");
	}
	sleep(1);
}

}

int main(int argc, char *argv[])
{
int rc;
MQTTClient client;

     MQTTClient_create(&client, ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL);

     
    MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
    conn_opts.username = USERNAME;
    conn_opts.password = PASSWORD;

#if USE_SSL
MQTTClient_SSLOptions ssl_opts = configureSSLOptions();
conn_opts.ssl = &ssl_opts;
#endif
conn_opts.keepAliveInterval = 10;
conn_opts.cleansession = 1;
MQTTClient_setCallbacks(client, client, conn_lost, on_message, NULL);
if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS)
{
printf("Failed to connect, return code %d\n", rc);
exit(-1);

    }
    else
    {
            printf("Connected to MQTT Broker!\n");
    }
    // subscribe topic
    MQTTClient_subscribe(client, SUB_TOPIC, QOS);


    while (1)
    {
            if (request_completed)
            {
                    request_completed = 0;
                    publish(client, PUB_TOPIC, res);  
            }
    }
    MQTTClient_unsubscribe(client, TOPIC);
    MQTTClient_disconnect(client, TIMEOUT);
    MQTTClient_destroy(&client);
    return rc;

}

@icraggs
Copy link
Contributor

icraggs commented Sep 2, 2024

The first thing is that the cause field in the connectionLost callback can be null, so it should be checked for that before printing.

Next, the program should not spend a long time in callbacks, which means no sleeping. The only API call allowed in connectionLost is connect - no subscribe or any other.

@SeaAndSand
Copy link

"The only API call allowed in connectionLost is connect。"
How should understand this sentence? In fact, I called B client's publish function in A client's connlost. When A client triggers connlost, it crashes very easily.

[19:13:25.384]Program received signal SIGSEGV, Segmentation fault.
[19:13:25.384]malloc_consolidate (av=av@entry=0x75b00010) at malloc.c:4141
[19:13:25.384]4141    malloc.c: No such file or directory.
19:13:29.134 bt
[19:13:29.134]#0  malloc_consolidate (av=av@entry=0x75b00010) at malloc.c:4141
[19:13:29.134]#1  0x76edd538 in _int_free (av=0x75b00010, p=, have_lock=0) at malloc.c:4049
[19:13:29.134]#2  0x76e757c4 in MQTTProperties_free () from /usr/lib/libpaho-mqtt3c.so.1
[19:13:29.134]Backtrace stopped: previous frame identical to this frame (corrupt stack?)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants