1

Hi all im working in linux libmodbus tcpip server client process I am reading the data from 3 different server, when all the server are connected then there is no issues but when i disconnect one server form the network then the following error is thrown.

"free(): double free detected in tcache 2 Aborted (core dumped)"

in the terminal. how do i fix it iam using multithreading here to connect two server simultaniously, the code is as follows

main.c

/*
 * Copyright © Stéphane Raimbault <stephane.raimbault@gmail.com>
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */
#include <stdio.h>
#include <pthread.h>

#include <errno.h>
#include <modbus.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>


// clang-format off
#ifdef _WIN32
# include <winsock2.h>
#else
# include <sys/socket.h>
#endif

/* For MinGW */
#ifndef MSG_NOSIGNAL
# define MSG_NOSIGNAL 0
#endif
// clang-format on

//#include "test-server.h"
#include "client-server.h"
pthread_mutex_t lock;

int main(int argc, char *argv[])
{

    pthread_t server, client,client1,client2;
    pthread_mutex_init(&lock, NULL);

   pthread_create(&server, NULL, &server_thread, NULL);
   pthread_create(&client, NULL, &client_thread, NULL);
   pthread_create(&client1, NULL, &client_1_thread, NULL);
   pthread_create(&client2, NULL, &client_2_thread, NULL);

  

   
   // use_backend = TCP;
   // ip_or_device = "192.168.1.200";
     

    // for (;;) 
    // {
    //    sleep(0.1);
        
    // }

    pthread_join(server, NULL);
    pthread_join(client, NULL);
    pthread_join(client1, NULL);
    pthread_join(client2, NULL);
    pthread_mutex_destroy(&lock);

    


    // printf("Quit the loop: %s\n", modbus_strerror(errno));

    // if (use_backend == TCP) {
    //     if (s != -1) {
    //         close(s);
    //     }
    // }
    // modbus_mapping_free(mb_mapping);
    // free(query);
    // /* For RTU */
    // modbus_close(ctx);
    // modbus_free(ctx);

    return 5;
}

client-server.c


 #include <stdio.h>
#include <pthread.h>

#include <errno.h>
#include <modbus.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>


// clang-format off
#ifdef _WIN32
# include <winsock2.h>
#else
# include <sys/socket.h>
#endif

/* For MinGW */
#ifndef MSG_NOSIGNAL
# define MSG_NOSIGNAL 0
#endif
// clang-format on

#include "test-server.h"
#include "client-server.h"

extern pthread_mutex_t lock;
  


uint16_t CS_Buffer[50];
 
enum {
    TCP,
    TCP_PI,
    RTU
};


 

void *server_thread(void *arg)
{
   // pthread_mutex_lock(&lock);
    int s = -1;
    modbus_t *ctx;
    modbus_mapping_t *mb_mapping;
    int rc;
    int i;
    int use_backend;
    uint8_t *query;
    int header_length;
    char *ip_or_device;
    uint16_t tab_reg[32];


    ctx = modbus_new_tcp("192.168.1.200", 1502);
    query = malloc(MODBUS_TCP_MAX_ADU_LENGTH);
    

    header_length = modbus_get_header_length(ctx);

    modbus_set_debug(ctx, TRUE);

    mb_mapping = modbus_mapping_new_start_address(UT_BITS_ADDRESS,
                                                  UT_BITS_NB,
                                                  UT_INPUT_BITS_ADDRESS,
                                                  UT_INPUT_BITS_NB,
                                                  UT_REGISTERS_ADDRESS,
                                                  UT_REGISTERS_NB_MAX,
                                                  UT_INPUT_REGISTERS_ADDRESS,
                                                  UT_INPUT_REGISTERS_NB);
    if (mb_mapping == NULL) {
        fprintf(stderr, "Failed to allocate the mapping: %s\n", modbus_strerror(errno));
        modbus_free(ctx);
       // return -1;
    }

    /* Examples from PI_MODBUS_300.pdf.
       Only the read-only input values are assigned. */

    /* Initialize input values that's can be only done server side. */
    modbus_set_bits_from_bytes(
        mb_mapping->tab_input_bits, 0, UT_INPUT_BITS_NB, UT_INPUT_BITS_TAB);

    /* Initialize values of INPUT REGISTERS */
    for (i = 0; i < UT_INPUT_REGISTERS_NB; i++) {
        mb_mapping->tab_input_registers[i] = UT_INPUT_REGISTERS_TAB[i];
    }
    // mb_mapping->tab_registers[0] = 0x0b;
    printf("Starting Server!\n");
    s = modbus_tcp_listen(ctx, 1);
    modbus_tcp_accept(ctx, &s);
    while(1)
    { 
   
     do {
            rc = modbus_receive(ctx, query);
            /* Filtered queries return 0 */
        } while (rc == 0);

        /* The connection is not closed on errors which require on reply such as
           bad CRC in RTU. */
        if (rc == -1 && errno != EMBBADCRC) {
            /* Quit */
           // break;
        }

        /* Special server behavior to test client */
        if (query[header_length] == 0x03) {
            /* Read holding registers */

            if (MODBUS_GET_INT16_FROM_INT8(query, header_length + 3) ==
                UT_REGISTERS_NB_SPECIAL) {
                printf("Set an incorrect number of values\n");
                MODBUS_SET_INT16_TO_INT8(
                    query, header_length + 3, UT_REGISTERS_NB_SPECIAL - 1);
            } else if (MODBUS_GET_INT16_FROM_INT8(query, header_length + 1) ==
                       UT_REGISTERS_ADDRESS_SPECIAL) {
                printf("Reply to this special register address by an exception\n");
                modbus_reply_exception(ctx, query, MODBUS_EXCEPTION_SLAVE_OR_SERVER_BUSY);
               // continue;
            } else if (MODBUS_GET_INT16_FROM_INT8(query, header_length + 1) ==
                       UT_REGISTERS_ADDRESS_INVALID_TID_OR_SLAVE) {
                const int RAW_REQ_LENGTH = 5;
                uint8_t raw_req[] = {(use_backend == RTU) ? INVALID_SERVER_ID : 0xFF,
                                     0x03,
                                     0x02,
                                     0x00,
                                     0x00};

                printf("Reply with an invalid TID or slave\n");
                modbus_send_raw_request(ctx, raw_req, RAW_REQ_LENGTH * sizeof(uint8_t));
               // continue;
            } else if (MODBUS_GET_INT16_FROM_INT8(query, header_length + 1) ==
                       UT_REGISTERS_ADDRESS_SLEEP_500_MS) {
                printf("Sleep 0.5 s before replying\n");
                usleep(500000);
            } else if (MODBUS_GET_INT16_FROM_INT8(query, header_length + 1) ==
                       UT_REGISTERS_ADDRESS_BYTE_SLEEP_5_MS) {
               // /* Test low level only available in TCP mode //
                ///* Catch the reply and send reply byte a byte //
                uint8_t req[] = "\x00\x1C\x00\x00\x00\x05\xFF\x03\x02\x00\x00";
                int req_length = 11;
                int w_s = modbus_get_socket(ctx);
                if (w_s == -1) {
                    fprintf(stderr, "Unable to get a valid socket in special test\n");
                  //  continue;
                }

               // /* Copy TID 
                req[1] = query[1];
                for (i = 0; i < req_length; i++) {
                    printf("(%.2X)", req[i]);
                    usleep(5000);
                    rc = send(w_s, (const char *) (req + i), 1, MSG_NOSIGNAL);
                    if (rc == -1) {
                       // break;
                    }
                }
               // continue;
            }
        }
       
        rc = modbus_reply(ctx, query, rc, mb_mapping);
        pthread_mutex_lock(&lock);
        mb_mapping->tab_registers[0] = CS_Buffer[0];
        printf("Server hoalding reg %u", mb_mapping->tab_registers[0]);
        pthread_mutex_unlock(&lock);
        if (rc == -1) {
            //break;
        }

    }

    modbus_close(ctx);
    modbus_free(ctx);
   // pthread_mutex_unlock(&lock);
    return NULL;
    

    
}


void *client_thread(void *arg)
{
   
     modbus_t *ctx;
     int rc;
     uint16_t tab_reg[32];
    while(1)
    {
    ctx = modbus_new_tcp("192.168.1.153", 502);
    if (modbus_connect(ctx) == -1) {
        fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno));
        modbus_free(ctx);
        //return -1;
    }
   

    
     rc = modbus_read_registers(ctx, 1, 9, tab_reg);
        if (rc == -1) {
            fprintf(stderr, "%s\n", modbus_strerror(errno));
        }
        else {
            int i;
            for (i=0; i < 2; i++) {
               // printf("register...\n");
                printf("reg[%d]=%d (0x%X)\n", i, tab_reg[i], tab_reg[i]);
                pthread_mutex_lock(&lock);
                CS_Buffer[i] = tab_reg[i];
                pthread_mutex_unlock(&lock);
            }
        }

        sleep(3);
    } 
        modbus_close(ctx);
        modbus_free(ctx);

         
    
          
        return NULL;
        
}

void *client_1_thread(void *arg)
{
   
     modbus_t *ctx;
     int rc;
     uint16_t tab_reg[32];
    while(1)
    {
    ctx = modbus_new_tcp("192.168.1.153", 503);
    if (modbus_connect(ctx) == -1) {
        fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno));
        modbus_free(ctx);
        //return -1;
    }
   

    
     rc = modbus_read_registers(ctx, 1, 9, tab_reg);
        if (rc == -1) {
            fprintf(stderr, "%s\n", modbus_strerror(errno));
        }
        else {
            int i;
            for (i=0; i < 2; i++) {
                //printf("register...\n");
                printf("reg_1[%d]=%d (0x%X)\n", i, tab_reg[i], tab_reg[i]);
                pthread_mutex_lock(&lock);
                //CS_Buffer[i] = tab_reg[i];
                pthread_mutex_unlock(&lock);
            }
        }

        sleep(3);
        modbus_close(ctx);
        modbus_free(ctx);
    } 
        

         
    
          
        return NULL;
        
}


void *client_2_thread(void *arg)
{
   
     modbus_t *ctx;
     int rc;
     uint16_t tab_reg[32];
    while(1)
    {
    ctx = modbus_new_tcp("192.168.1.153", 504);
    if (modbus_connect(ctx) == -1) {
        fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno));
        modbus_free(ctx);
        //return -1;
    }
   

    
     rc = modbus_read_registers(ctx, 1, 9, tab_reg);
        if (rc == -1) {
            fprintf(stderr, "%s\n", modbus_strerror(errno));
        }
        else {
            int i;
            for (i=0; i < 2; i++) {
                //printf("register...\n");
                printf("reg_2[%d]=%d (0x%X)\n", i, tab_reg[i], tab_reg[i]);
                pthread_mutex_lock(&lock);
                //CS_Buffer[i] = tab_reg[i];
                pthread_mutex_unlock(&lock);
            }
        }

        sleep(3);
        modbus_close(ctx);
        modbus_free(ctx);
    } 
        

         
    
          
        return NULL;
        
}

Any thoughts kindly share .. thankyou

I tried to print the error in the terminal when the server is not responding but even that error message is not being printed in the display when the server is disconnected.

Nagaraj JP
  • 11
  • 2

0 Answers0