简体   繁体   中英

Segmentation fault in my server (valgrind logs)

There is a problem that I've been driving with for more than 3 weeks. Please help with advice. I beg you very much! I am new to C ++. Even small tips can help me!

It is required to create a server that must store the integer values ​​of various signals. A client can connect to this server and receive this data.

Data transmission between the client and server occurs according to the industrial protocol IEC-60870-5-104 TCP / IP.

I used a ready-made library that implements this IEC-104 protocol in C and created a C ++ program. ( GIT link )

I wrote a test program (main.cpp). A list of signals with values ​​(for example, 450 elements) arrives at the input, then this list is transferred to the Map dictionary. The program compiles and runs on Linux Debian from the command line (gcc version 9.2.1 20191109 (Debian 9.2.1-19) ). There is no debugger here.

Then, in an infinite loop, the functions of changing the quality label and signal value on the server are called one by one. The implementation of the functions is almost the same. The difference is that SetBadQuality works for several values ​​at once, and ChangeValue works for one specific signal.

Modified signals (it does not matter if the quality label or value has changed) are added to the queue (CS104_Slave_enqueueASDU), after which the client receives data from this queue. The library says that when the queue is full, they begin to overwrite the older values ​​in this queue. And as soon as the client receives data from the queue, they are deleted in the queue. To send data to the client, ASDU (Application Service Data Unit) packets in the TSP / IP are used.

At first, the program works correctly. The client successfully accepts the changed signal values. Their quality is changing, their values ​​are changing. Everything works well.

But a certain point in time flies segFault. The error crashes only when the client is connected to the server. If the client is not connected to the server, then the program works correctly without errors (but seg fault appears immediately after the client connects to the server).

Used the valgrind utility to generate log messages.

In fact, no in-depth study of this library is required. Can someone tell me what my error is specifically in C ++? Why does a seg fault crash?

If I change the number of elements in a List (for example, from 450 elements to 500), the error appears at another point in time.

IEC104Server.h

#include <stdlib.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <map>
#include <iostream>
#include <list>
#include "cs104_slave.h"
#include <string>
#include "hal_thread.h"
#include "hal_time.h"
#include "iec60870_slave.h"
#include "apl_types_internal.h"
#include <unistd.h>
#include <sys/time.h>
#include <errno.h>

using namespace std;

class IEC60870
{
    public:     
        IEC60870(int slave_size_1, int slave_size_2, const char* ip_client, CS104_ServerMode serverMode);   //Конструктор
        ~IEC60870();
        bool IO_create_int(std::list<int> modbus_list, int addr_start, int id_group, bool command_possibl);
        bool ChangeIOValue_int(int value, int ioa);     
        enum map_type_enum { bool_name, float_name, int_name };
        bool SetBadQuality(map_type_enum map_type, int addr_start, int count);

    private:
        bool running = true;
        CS104_Slave slave;              
        struct MBdata
        {
            int id_group;
            int value;
            uint64_t timestamp;
            QualityDescriptor quality;
            bool command_possibl;
        };

        static map <int,MBdata> Dictionary_map_IO_int;

        static void connectionEventHandler(void* parameter, IMasterConnection con, CS104_PeerConnectionEvent event);

};

simple_server.cpp

#include "IEC104Server.h"

map <int,IEC60870::MBdata> IEC60870::Dictionary_map_IO_int;

IEC60870::IEC60870(int slave_size_1, int slave_size_2, const char* ip_client, CS104_ServerMode serverMode)
{
    slave = CS104_Slave_create(slave_size_1, slave_size_2);
    // Functions list such as set ip address, server mode, event handlers
    CS104_Slave_setLocalAddress(slave, ip_client);
    CS104_Slave_setServerMode(slave, serverMode);
    CS104_Slave_setConnectionEventHandler(slave, connectionEventHandler, NULL);
    CS104_Slave_start(slave);
    Thread_sleep(500);
}

IEC60870::~IEC60870()
{
    if (CS104_Slave_isRunning(slave) == false)
        CS104_Slave_stop(slave);
    CS104_Slave_destroy(slave);
}

//--------------------------------------------------------------------------------------------------------
bool IEC60870::IO_create_int(std::list<int> modbus_list, int addr_start, int id_group, bool command_possibl) //Create Dictionary-Map from input List (list created in main.cpp)
{   
    uint64_t currentTimestamp = Hal_getTimeInMs();
    for (int n : modbus_list)
    {
        MBdata data_i {id_group, n, currentTimestamp, IEC60870_QUALITY_GOOD, command_possibl}; // Create struct MBdata
        Dictionary_map_IO_int.insert ( pair<int,MBdata>(addr_start/*IOA*/,data_i) ); // Create Dictionary-Map from input List (list created in main.cpp)
        addr_start++;
    }
    return true;
}
//--------------------------------------------------------------------------------------------------------
bool IEC60870::ChangeIOValue_int(int value, int ioa)
{
    CS101_AppLayerParameters alParams2 = CS104_Slave_getAppLayerParameters(slave);
    if (Dictionary_map_IO_int.empty() == true)
    {
        printf ("Error. Map int not created\n");
        return false;
    }
    uint64_t currentTimestamp = Hal_getTimeInMs();
    struct sCP56Time2a Time;
    CP56Time2a_createFromMsTimestamp(&Time, currentTimestamp);
    auto it = Dictionary_map_IO_int.find(ioa); // Find ioa and MBdata-struct in Map
    if( it == Dictionary_map_IO_int.end() )
    {
        printf ("Error changed IOA int\n");
        return false;
    }
    (it->second).value = value; // Update value in Map
    (it->second).timestamp = currentTimestamp; // Update timestamp in Map
    CS101_ASDU AsduChanged = CS101_ASDU_create(alParams2, false, CS101_COT_PERIODIC, 0, 1, false, false); // Create new ASDU
    InformationObject io = (InformationObject) MeasuredValueScaledWithCP56Time2a_create(NULL, ioa, value, IEC60870_QUALITY_GOOD, &Time); // Create new io-struct
    CS101_ASDU_addInformationObject(AsduChanged, io); // Add io in ASDU
    InformationObject_destroy(io);
    CS104_Slave_enqueueASDU(slave, AsduChanged);
    CS101_ASDU_destroy(AsduChanged);
    return true;
}
//--------------------------------------------------------------------------------------------------------
/*Анализ установки соединения клиент-сервер*/
void IEC60870::connectionEventHandler(void* parameter, IMasterConnection con, CS104_PeerConnectionEvent event)
{
    if (event == CS104_CON_EVENT_CONNECTION_OPENED) {
        printf("Connection opened (%p)\n", con);
    }
    else if (event == CS104_CON_EVENT_CONNECTION_CLOSED) {
        printf("Connection closed (%p)\n", con);
    }
    else if (event == CS104_CON_EVENT_ACTIVATED) {
        printf("Connection activated (%p)\n", con);
    }
    else if (event == CS104_CON_EVENT_DEACTIVATED) {
        printf("Connection deactivated (%p)\n", con);
    }
}
//--------------------------------------------------------------------------------------------------------
bool IEC60870::SetBadQuality(map_type_enum map_type, int ioa_start, int count)
{
    int for_count = ioa_start + count;
    CS101_AppLayerParameters alParams = CS104_Slave_getAppLayerParameters(slave);
    uint64_t currentTimestamp = Hal_getTimeInMs();
    struct sCP56Time2a Time;
    CP56Time2a_createFromMsTimestamp(&Time, currentTimestamp);  

    if (map_type == int_name/*int map*/)
    {
        if (Dictionary_map_IO_int.empty() == true)
        {
            printf ("Error. Map int not created\n");
            return false;
        }
        CS101_ASDU asduInt = CS101_ASDU_create(alParams, false, CS101_COT_PERIODIC, 0, 1, false, false);
        InformationObject io = (InformationObject) MeasuredValueScaledWithCP56Time2a_create(NULL, 0, 0, IEC60870_QUALITY_INVALID, &Time);
        for (ioa_start; ioa_start < for_count; ioa_start++)
        {       
            auto it = Dictionary_map_IO_int.find(ioa_start);
            if( it == Dictionary_map_IO_int.end() )
            {
                printf ("Error. This int IOA is not in Map\n");
                return false;
            }       
            (it->second).quality = IEC60870_QUALITY_INVALID;            
            bool added = CS101_ASDU_addInformationObject(asduInt, (InformationObject) MeasuredValueScaledWithCP56Time2a_create((MeasuredValueScaledWithCP56Time2a)io, ioa_start, (it->second).value, IEC60870_QUALITY_INVALID, &Time));
            if (!added)
            {
                CS104_Slave_enqueueASDU(slave, asduInt);
                CS101_ASDU_destroy(asduInt);
                asduInt = CS101_ASDU_create(alParams, false, CS101_COT_PERIODIC, 0, 1, false, false);
                CS101_ASDU_addInformationObject(asduInt, (InformationObject) MeasuredValueScaledWithCP56Time2a_create((MeasuredValueScaledWithCP56Time2a)io, ioa_start, (it->second).value, IEC60870_QUALITY_INVALID, &Time));
            }
        }
        InformationObject_destroy(io);
        CS104_Slave_enqueueASDU(slave, asduInt);
        CS101_ASDU_destroy(asduInt);
    }
    else 
    {   
        printf ("Такого типа Map не существует\n");
        return false;
    }
    return true;
}

main.cpp

#include "IEC104Server.h"

int
main(int argc, char** argv)
{
    IEC60870 server(50, 50, "0.0.0.0", CS104_MODE_SINGLE_REDUNDANCY_GROUP); // create server object

    std::list<int> ints_list; // create input list  
    for (int i=0; i<450; i++)
    {
        ints_list.push_back(i);
    }   
    usleep(10000); //pause 0.01 second
    printf("list created\n");

    server.IO_create_int(ints_list, 300, 4, true); // create Map. Start address "300". "4" and "true" not important parameters
    usleep(20000000); //pause 20 second
    printf("map created\n");    

    int value = 0;
    while(true)
    {
        printf ("start bad quiality function\n");
        bool bad_qual = server.SetBadQuality(IEC60870::int_name,300,450); // Start address "300". Count signals "450"   
        usleep(10000000); //pause 10 second

        if (bad_qual == false)
        {
            printf("bad quality is not successful\n");
        }   
        printf ("start change value function\n");

        // In this loop, the function of changing the value is called:
        for (int i=0; i<450; i++) // "450" is quantity signals
        {
            int ioa = i + 300; // Start address "300"
            bool test = server.ChangeIOValue_int(value, ioa);
            if (test == false)
            {
                printf ("change value is not successful\n");
            }
            value++;
            if (value == 10000)
            {
                printf ("null value\n");
                value = 0;
            }
            usleep(100000);  //pause 0.1 second
        }
        usleep(100000); //pause 0.1 second
    }
}

I had to remove the same pieces of valgrind logs, because I had to meet the limit of 30,000 characters in the text. Deleted logs from different sites. Therefore, do not be afraid that somewhere there may be a break in the logical chain. I tried to leave the point and remove only the same sections of the text. If necessary, I can send the full text of the logs!

valgrind logs

moxa@Moxa:~/source/Rus_test_can_del$ sudo valgrind --leak-check=full --track-origins=yes  --show-leak-kinds=all ./program
==3374== Memcheck, a memory error detector
==3374== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==3374== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==3374== Command: ./program
==3374==
list created
Connection opened (0x4b56064)
Connection activated (0x4b56064)
map created
start bad quiality function
start change value function
start bad quiality function
==3374== Thread 3:
==3374== Invalid read of size 1
==3374==    at 0x4845704: memcpy (vg_replace_strmem.c:1036)
==3374==    by 0x116063: MessageQueue_getNextWaitingASDU (cs104_slave.c:332)
==3374==    by 0x117C75: sendNextLowPriorityASDU (cs104_slave.c:2180)
==3374==    by 0x117DC9: sendWaitingASDUs (cs104_slave.c:2258)
==3374==    by 0x11816B: connectionHandlingThread (cs104_slave.c:2431)
==3374==    by 0x11AB1F: destroyAutomaticThread (thread_linux.c:87)
==3374==    by 0x4861D2F: start_thread (pthread_create.c:479)
==3374==    by 0x4A8B07B: ??? (clone.S:73)
==3374==  Address 0x4b5b0b8 is 0 bytes after a block of size 13,600 alloc'd
==3374==    at 0x4842290: calloc (vg_replace_malloc.c:762)
==3374==    by 0x11AD0B: Memory_calloc (lib_memory.c:56)
==3374==    by 0x115D25: MessageQueue_initialize (cs104_slave.c:128)
==3374==    by 0x115D75: MessageQueue_create (cs104_slave.c:149)
==3374==    by 0x1168B7: initializeMessageQueues (cs104_slave.c:1066)
==3374==    by 0x118EAB: CS104_Slave_start (cs104_slave.c:3217)
==3374==    by 0x10A33B: IEC60870::IEC60870(int, int, char const*, CS104_ServerMode) (in /home/moxa/source/Rus_test_can_del/program)
==3374==
==3374== Invalid read of size 1
==3374==    at 0x4845714: memcpy (vg_replace_strmem.c:1036)
==3374==    by 0x116063: MessageQueue_getNextWaitingASDU (cs104_slave.c:332)
==3374==    by 0x117C75: sendNextLowPriorityASDU (cs104_slave.c:2180)
==3374==    by 0x117DC9: sendWaitingASDUs (cs104_slave.c:2258)
==3374==    by 0x11816B: connectionHandlingThread (cs104_slave.c:2431)
==3374==    by 0x11AB1F: destroyAutomaticThread (thread_linux.c:87)
==3374==    by 0x4861D2F: start_thread (pthread_create.c:479)
==3374==    by 0x4A8B07B: ??? (clone.S:73)
==3374==  Address 0x4b5b0b9 is 1 bytes after a block of size 13,600 alloc'd
==3374==    at 0x4842290: calloc (vg_replace_malloc.c:762)
==3374==    by 0x11AD0B: Memory_calloc (lib_memory.c:56)
==3374==    by 0x115D25: MessageQueue_initialize (cs104_slave.c:128)
==3374==    by 0x115D75: MessageQueue_create (cs104_slave.c:149)
==3374==    by 0x1168B7: initializeMessageQueues (cs104_slave.c:1066)
==3374==    by 0x118EAB: CS104_Slave_start (cs104_slave.c:3217)
==3374==    by 0x10A33B: IEC60870::IEC60870(int, int, char const*, CS104_ServerMode) (in /home/moxa/source/Rus_test_can_del/program)
==3374==
==3374== Invalid write of size 4
==3374==    at 0x484561C: memcpy (vg_replace_strmem.c:1036)
==3374==    by 0x1160A7: MessageQueue_getNextWaitingASDU (cs104_slave.c:341)
==3374==    by 0x117C75: sendNextLowPriorityASDU (cs104_slave.c:2180)
==3374==    by 0x117DC9: sendWaitingASDUs (cs104_slave.c:2258)
==3374==    by 0x11816B: connectionHandlingThread (cs104_slave.c:2431)
==3374==    by 0x11AB1F: destroyAutomaticThread (thread_linux.c:87)
==3374==    by 0x4861D2F: start_thread (pthread_create.c:479)
==3374==    by 0x4A8B07B: ??? (clone.S:73)
==3374==  Address 0x4b5e5bc is 4 bytes inside a block of size 48 free'd
==3374==    at 0x4840C70: free (vg_replace_malloc.c:540)
==3374==    by 0x4A7A609: freeaddrinfo (getaddrinfo.c:2524)
==3374==    by 0x11A3CB: prepareServerAddress (socket_linux.c:136)
==3374==    by 0x11A485: TcpServerSocket_create (socket_linux.c:173)
==3374==    by 0x118B77: serverThread (cs104_slave.c:2999)
==3374==    by 0x4861D2F: start_thread (pthread_create.c:479)
==3374==    by 0x4A8B07B: ??? (clone.S:73)
==3374==  Block was alloc'd at
==3374==    at 0x483F5F8: malloc (vg_replace_malloc.c:309)
==3374==    by 0x4A79877: gaih_inet.constprop.0 (getaddrinfo.c:1057)
==3374==    by 0x4A7A709: getaddrinfo (getaddrinfo.c:2254)
==3374==    by 0x11A3A5: prepareServerAddress (socket_linux.c:128)
==3374==    by 0x11A485: TcpServerSocket_create (socket_linux.c:173)
==3374==    by 0x118B77: serverThread (cs104_slave.c:2999)
==3374==    by 0x4861D2F: start_thread (pthread_create.c:479)
==3374==    by 0x4A8B07B: ??? (clone.S:73)
==3374==
==3374== Invalid write of size 4
==3374==    at 0x4845624: memcpy (vg_replace_strmem.c:1036)
==3374==    by 0x1160A7: MessageQueue_getNextWaitingASDU (cs104_slave.c:341)
==3374==    by 0x117C75: sendNextLowPriorityASDU (cs104_slave.c:2180)
==3374==    by 0x117DC9: sendWaitingASDUs (cs104_slave.c:2258)
==3374==    by 0x11816B: connectionHandlingThread (cs104_slave.c:2431)
==3374==    by 0x11AB1F: destroyAutomaticThread (thread_linux.c:87)
==3374==    by 0x4861D2F: start_thread (pthread_create.c:479)
==3374==    by 0x4A8B07B: ??? (clone.S:73)
==3374==  Address 0x4b5e5c0 is 8 bytes inside a block of size 48 free'd
==3374==    at 0x4840C70: free (vg_replace_malloc.c:540)
==3374==    by 0x4A7A609: freeaddrinfo (getaddrinfo.c:2524)
==3374==    by 0x11A3CB: prepareServerAddress (socket_linux.c:136)
==3374==    by 0x11A485: TcpServerSocket_create (socket_linux.c:173)
==3374==    by 0x118B77: serverThread (cs104_slave.c:2999)
==3374==    by 0x4861D2F: start_thread (pthread_create.c:479)
==3374==    by 0x4A8B07B: ??? (clone.S:73)
==3374==  Block was alloc'd at
==3374==    at 0x483F5F8: malloc (vg_replace_malloc.c:309)
==3374==    by 0x4A79877: gaih_inet.constprop.0 (getaddrinfo.c:1057)
==3374==    by 0x4A7A709: getaddrinfo (getaddrinfo.c:2254)
==3374==    by 0x11A3A5: prepareServerAddress (socket_linux.c:128)
==3374==    by 0x11A485: TcpServerSocket_create (socket_linux.c:173)
==3374==    by 0x118B77: serverThread (cs104_slave.c:2999)
==3374==    by 0x4861D2F: start_thread (pthread_create.c:479)
==3374==    by 0x4A8B07B: ??? (clone.S:73)
==3374==
==3374== Invalid read of size 2
==3374==    at 0x48456D0: memcpy (vg_replace_strmem.c:1036)
==3374==    by 0x117C8F: sendNextLowPriorityASDU (cs104_slave.c:2183)
==3374==    by 0x117DC9: sendWaitingASDUs (cs104_slave.c:2258)
==3374==    by 0x11816B: connectionHandlingThread (cs104_slave.c:2431)
==3374==    by 0x11AB1F: destroyAutomaticThread (thread_linux.c:87)
==3374==    by 0x4861D2F: start_thread (pthread_create.c:479)
==3374==    by 0x4A8B07B: ??? (clone.S:73)
==3374==  Address 0x4b5e5cc is 20 bytes inside a block of size 48 free'd
==3374==    at 0x4840C70: free (vg_replace_malloc.c:540)
==3374==    by 0x4A7A609: freeaddrinfo (getaddrinfo.c:2524)
==3374==    by 0x11A3CB: prepareServerAddress (socket_linux.c:136)
==3374==    by 0x11A485: TcpServerSocket_create (socket_linux.c:173)
==3374==    by 0x118B77: serverThread (cs104_slave.c:2999)
==3374==    by 0x4861D2F: start_thread (pthread_create.c:479)
==3374==    by 0x4A8B07B: ??? (clone.S:73)
==3374==  Block was alloc'd at
==3374==    at 0x483F5F8: malloc (vg_replace_malloc.c:309)
==3374==    by 0x4A79877: gaih_inet.constprop.0 (getaddrinfo.c:1057)
==3374==    by 0x4A7A709: getaddrinfo (getaddrinfo.c:2254)
==3374==    by 0x11A3A5: prepareServerAddress (socket_linux.c:128)
==3374==    by 0x11A485: TcpServerSocket_create (socket_linux.c:173)
==3374==    by 0x118B77: serverThread (cs104_slave.c:2999)
==3374==    by 0x4861D2F: start_thread (pthread_create.c:479)
==3374==    by 0x4A8B07B: ??? (clone.S:73)
==3374==
Connection closed (0x4b56064)
==3374== Invalid read of size 1
==3374==    at 0x4845704: memcpy (vg_replace_strmem.c:1036)
==3374==    by 0x11613B: MessageQueue_setWaitingForTransmissionWhenNotConfirmed (cs104_slave.c:376)
==3374==    by 0x117FEB: CS104_Slave_removeConnection (cs104_slave.c:2353)
==3374==    by 0x1181C1: connectionHandlingThread (cs104_slave.c:2442)
==3374==    by 0x11AB1F: destroyAutomaticThread (thread_linux.c:87)
==3374==    by 0x4861D2F: start_thread (pthread_create.c:479)
==3374==    by 0x4A8B07B: ??? (clone.S:73)
==3374==  Address 0x4b5b0b8 is 0 bytes after a block of size 13,600 alloc'd
==3374==    at 0x4842290: calloc (vg_replace_malloc.c:762)
==3374==    by 0x11AD0B: Memory_calloc (lib_memory.c:56)
==3374==    by 0x115D25: MessageQueue_initialize (cs104_slave.c:128)
==3374==    by 0x115D75: MessageQueue_create (cs104_slave.c:149)
==3374==    by 0x1168B7: initializeMessageQueues (cs104_slave.c:1066)
==3374==    by 0x118EAB: CS104_Slave_start (cs104_slave.c:3217)
==3374==    by 0x10A33B: IEC60870::IEC60870(int, int, char const*, CS104_ServerMode) (in /home/moxa/source/Rus_test_can_del/program)
==3374==
==3374== Invalid read of size 2
==3374==    at 0x48456E0: memcpy (vg_replace_strmem.c:1036)
==3374==    by 0x11613B: MessageQueue_setWaitingForTransmissionWhenNotConfirmed (cs104_slave.c:376)
==3374==    by 0x117FEB: CS104_Slave_removeConnection (cs104_slave.c:2353)
==3374==    by 0x1181C1: connectionHandlingThread (cs104_slave.c:2442)
==3374==    by 0x11AB1F: destroyAutomaticThread (thread_linux.c:87)
==3374==    by 0x4861D2F: start_thread (pthread_create.c:479)
==3374==    by 0x4A8B07B: ??? (clone.S:73)
==3374==  Address 0x4b5e6ae is 2 bytes before a block of size 12 alloc'd
==3374==    at 0x483FDE8: operator new(unsigned int) (vg_replace_malloc.c:338)
==3374==    by 0x10A2A7: __gnu_cxx::new_allocator<std::_List_node<int> >::allocate(unsigned int, void const*) (in /home/moxa/source/Rus_test_can_del/program)
==3374==
==3374== Conditional jump or move depends on uninitialised value(s)
==3374==    at 0x1160F6: MessageQueue_setWaitingForTransmissionWhenNotConfirmed (cs104_slave.c:364)
==3374==    by 0x117FEB: CS104_Slave_removeConnection (cs104_slave.c:2353)
==3374==    by 0x1181C1: connectionHandlingThread (cs104_slave.c:2442)
==3374==    by 0x11AB1F: destroyAutomaticThread (thread_linux.c:87)
==3374==    by 0x4861D2F: start_thread (pthread_create.c:479)
==3374==    by 0x4A8B07B: ??? (clone.S:73)
==3374==  Uninitialised value was created by a heap allocation
==3374==    at 0x483F5F8: malloc (vg_replace_malloc.c:309)
==3374==    by 0x4A362BD: _IO_file_doallocate (filedoalloc.c:101)
==3374==    by 0x4A4079B: _IO_doallocbuf (genops.c:347)
==3374==    by 0x4A3FF0F: _IO_file_overflow@@GLIBC_2.4 (fileops.c:749)
==3374==    by 0x4A3F4A5: _IO_new_file_xsputn (fileops.c:1248)
==3374==    by 0x4A3F4A5: _IO_file_xsputn@@GLIBC_2.4 (fileops.c:1201)
==3374==    by 0x4A37EF3: puts (ioputs.c:40)
==3374==    by 0x109915: main (in /home/moxa/source/Rus_test_can_del/program)
==3374==
==3374== Use of uninitialised value of size 4
==3374==    at 0x4845704: memcpy (vg_replace_strmem.c:1036)
==3374==    by 0x11613B: MessageQueue_setWaitingForTransmissionWhenNotConfirmed (cs104_slave.c:376)
==3374==    by 0x117FEB: CS104_Slave_removeConnection (cs104_slave.c:2353)
==3374==    by 0x1181C1: connectionHandlingThread (cs104_slave.c:2442)
==3374==    by 0x11AB1F: destroyAutomaticThread (thread_linux.c:87)
==3374==    by 0x4861D2F: start_thread (pthread_create.c:479)
==3374==    by 0x4A8B07B: ??? (clone.S:73)
==3374==  Uninitialised value was created by a stack allocation
==3374==    at 0x115DE6: MessageQueue_enqueueASDU (cs104_slave.c:190)

==3374== Conditional jump or move depends on uninitialised value(s)
==3374==    at 0x4845714: memcpy (vg_replace_strmem.c:1036)
==3374==    by 0x11613B: MessageQueue_setWaitingForTransmissionWhenNotConfirmed (cs104_slave.c:376)
==3374==    by 0x117FEB: CS104_Slave_removeConnection (cs104_slave.c:2353)
==3374==    by 0x1181C1: connectionHandlingThread (cs104_slave.c:2442)
==3374==    by 0x11AB1F: destroyAutomaticThread (thread_linux.c:87)
==3374==    by 0x4861D2F: start_thread (pthread_create.c:479)
==3374==    by 0x4A8B07B: ??? (clone.S:73)
==3374==  Uninitialised value was created by a stack allocation
==3374==    at 0x115DE6: MessageQueue_enqueueASDU (cs104_slave.c:190)
==3374==
==3374== Use of uninitialised value of size 4
==3374==    at 0x4845610: memcpy (vg_replace_strmem.c:1036)
==3374==    by 0x11613B: MessageQueue_setWaitingForTransmissionWhenNotConfirmed (cs104_slave.c:376)
==3374==    by 0x117FEB: CS104_Slave_removeConnection (cs104_slave.c:2353)
==3374==    by 0x1181C1: connectionHandlingThread (cs104_slave.c:2442)
==3374==    by 0x11AB1F: destroyAutomaticThread (thread_linux.c:87)
==3374==    by 0x4861D2F: start_thread (pthread_create.c:479)
==3374==    by 0x4A8B07B: ??? (clone.S:73)
==3374==  Uninitialised value was created by a stack allocation
==3374==    at 0x115DE6: MessageQueue_enqueueASDU (cs104_slave.c:190)
==3374==
==3374== Conditional jump or move depends on uninitialised value(s)
==3374==    at 0x4845640: memcpy (vg_replace_strmem.c:1036)
==3374==    by 0x11613B: MessageQueue_setWaitingForTransmissionWhenNotConfirmed (cs104_slave.c:376)
==3374==    by 0x117FEB: CS104_Slave_removeConnection (cs104_slave.c:2353)
==3374==    by 0x1181C1: connectionHandlingThread (cs104_slave.c:2442)
==3374==    by 0x11AB1F: destroyAutomaticThread (thread_linux.c:87)
==3374==    by 0x4861D2F: start_thread (pthread_create.c:479)
==3374==    by 0x4A8B07B: ??? (clone.S:73)
==3374==  Uninitialised value was created by a stack allocation
==3374==    at 0x115DE6: MessageQueue_enqueueASDU (cs104_slave.c:190)
==3374==
==3374== Use of uninitialised value of size 4
==3374==    at 0x48456D0: memcpy (vg_replace_strmem.c:1036)
==3374==    by 0x11613B: MessageQueue_setWaitingForTransmissionWhenNotConfirmed (cs104_slave.c:376)
==3374==    by 0x117FEB: CS104_Slave_removeConnection (cs104_slave.c:2353)
==3374==    by 0x1181C1: connectionHandlingThread (cs104_slave.c:2442)
==3374==    by 0x11AB1F: destroyAutomaticThread (thread_linux.c:87)
==3374==    by 0x4861D2F: start_thread (pthread_create.c:479)
==3374==    by 0x4A8B07B: ??? (clone.S:73)
==3374==  Uninitialised value was created by a stack allocation
==3374==    at 0x115DE6: MessageQueue_enqueueASDU (cs104_slave.c:190)
==3374==
==3374== Conditional jump or move depends on uninitialised value(s)
==3374==    at 0x48456E0: memcpy (vg_replace_strmem.c:1036)
==3374==    by 0x11613B: MessageQueue_setWaitingForTransmissionWhenNotConfirmed (cs104_slave.c:376)
==3374==    by 0x117FEB: CS104_Slave_removeConnection (cs104_slave.c:2353)
==3374==    by 0x1181C1: connectionHandlingThread (cs104_slave.c:2442)
==3374==    by 0x11AB1F: destroyAutomaticThread (thread_linux.c:87)
==3374==    by 0x4861D2F: start_thread (pthread_create.c:479)
==3374==    by 0x4A8B07B: ??? (clone.S:73)
==3374==  Uninitialised value was created by a stack allocation
==3374==    at 0x115DE6: MessageQueue_enqueueASDU (cs104_slave.c:190)
==3374==
start change value function
==3374==
==3374== Process terminating with default action of signal 11 (SIGSEGV)
==3374==  Bad permissions for mapped region at address 0x4F5102A
==3374==    at 0x48456D0: memcpy (vg_replace_strmem.c:1036)
==3374==    by 0x11613B: MessageQueue_setWaitingForTransmissionWhenNotConfirmed (cs104_slave.c:376)
==3374==    by 0x117FEB: CS104_Slave_removeConnection (cs104_slave.c:2353)
==3374==    by 0x1181C1: connectionHandlingThread (cs104_slave.c:2442)
==3374==    by 0x11AB1F: destroyAutomaticThread (thread_linux.c:87)
==3374==    by 0x4861D2F: start_thread (pthread_create.c:479)
==3374==    by 0x4A8B07B: ??? (clone.S:73)
==3374==
==3374== HEAP SUMMARY:
==3374==     in use at exit: 59,972 bytes in 936 blocks
==3374==   total heap usage: 2,364 allocs, 1,428 frees, 239,400 bytes allocated
==3374== LEAK SUMMARY:
==3374==    definitely lost: 0 bytes in 0 blocks
==3374==    indirectly lost: 0 bytes in 0 blocks
==3374==      possibly lost: 288 bytes in 2 blocks
==3374==    still reachable: 59,684 bytes in 934 blocks
==3374==         suppressed: 0 bytes in 0 blocks
==3374==
==3374== For lists of detected and suppressed errors, rerun with: -s
==3374== ERROR SUMMARY: 4187297 errors from 41 contexts (suppressed: 0 from 0)
Segmentation fault

You need to go through the errors one by one and fix them. Take the first error

==3374== Invalid read of size 1
==3374==    at 0x4845704: memcpy (vg_replace_strmem.c:1036)
==3374==    by 0x116063: MessageQueue_getNextWaitingASDU (cs104_slave.c:332)
==3374==    by 0x117C75: sendNextLowPriorityASDU (cs104_slave.c:2180)
==3374==    by 0x117DC9: sendWaitingASDUs (cs104_slave.c:2258)
==3374==    by 0x11816B: connectionHandlingThread (cs104_slave.c:2431)
==3374==    by 0x11AB1F: destroyAutomaticThread (thread_linux.c:87)
==3374==    by 0x4861D2F: start_thread (pthread_create.c:479)
==3374==    by 0x4A8B07B: ??? (clone.S:73)
==3374==  Address 0x4b5b0b8 is 0 bytes after a block of size 13,600 alloc'd
==3374==    at 0x4842290: calloc (vg_replace_malloc.c:762)
==3374==    by 0x11AD0B: Memory_calloc (lib_memory.c:56)
==3374==    by 0x115D25: MessageQueue_initialize (cs104_slave.c:128)
==3374==    by 0x115D75: MessageQueue_create (cs104_slave.c:149)
==3374==    by 0x1168B7: initializeMessageQueues (cs104_slave.c:1066)
==3374==    by 0x118EAB: CS104_Slave_start (cs104_slave.c:3217)
==3374==    by 0x10A33B: IEC60870::IEC60870(int, int, char const*, CS104_ServerMode) (in /home/moxa/source/Rus_test_can_del/program)

The first part says where the error occurred. The second part says where the memory that is the source of the error was allocated. I'll start with the second part.

==3374==  Address 0x4b5b0b8 is 0 bytes after a block of size 13,600 alloc'd

This gives the address of the memory block, which isn't much use. It also says that the block is 13600 bytes long and that your invalid access is the first byte after that block.

==3374==    at 0x4842290: calloc (vg_replace_malloc.c:762)

This is the function that Valgrind used to replace calloc so that Valgrind can trace memory allocations. You can ignore this line.

==3374==    by 0x11AD0B: Memory_calloc (lib_memory.c:56)

This looks like your wrapper around calloc . Again, you can probably ignore this.

==3374==    by 0x115D25: MessageQueue_initialize (cs104_slave.c:128)

This is where you are really asking for the memory. You need to look here to check whether you have not made a mistake and that you should be allocating more memory here. Personally I suspect that this is not the case.

Now let's look at the first block.

==3374== Invalid read of size 1

This is saying that the invalid operation is on one byte. So it means that the fundamental type causing the invalid operation is a char or bool ( char considering the following parts to the error).

==3374==    at 0x4845704: memcpy (vg_replace_strmem.c:1036)

Again, this is a replacement function provided by Valgrind. You can ignore this.

==3374==    by 0x116063: MessageQueue_getNextWaitingASDU (cs104_slave.c:332)

Now this is likely to be where the real error is.

The two common causes for this kind of error are

  1. Out by one error in a loop
    For instance, in pseudocode
// allocate 10 items, with indexes 0 to 9
mem = new int[10];
for (int i = 0 i <= 10; ++i)
   // but access **11** items from 0 to 10 inclusive
   do something with mem[i]
  1. A string operation that omits the trailing nul character
    Again a psuedocode example
// inputString contains "hello" which is 6 bytes long (5 letters plus nul)
// but strlen doesn't count the nul so returns 5
len = strlen(inputString);
// allocate an array of 5 characters
copyString = (char*)malloc(len);
// copies 6 characters into a 5 character array!
memcpy(copyString, inputString, len+1);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM