Ошибка сегментации на моем сервере (журналы valgrind) - PullRequest
1 голос
/ 01 апреля 2020

Есть проблема, с которой я езжу более 3 недель. Пожалуйста, помогите с советом. Я очень прошу вас! Я новичок в C ++. Даже небольшие советы могут помочь мне!

Требуется создать сервер, который должен хранить целочисленные значения различных сигналов. Клиент может подключиться к этому серверу и получить эти данные.

Передача данных между клиентом и сервером происходит в соответствии с промышленным протоколом IEC -60870-5-104 TCP / IP.

Я использовал готовую библиотеку, которая реализует этот протокол IEC -104 в C и создал программу C ++. (GIT ссылка )

Я написал тестовую программу (основная. cpp). На вход поступает список сигналов со значениями (например, 450 элементов), затем этот список переносится в словарь карт. Программа компилируется и запускается на Linux Debian из командной строки (g cc версия 9.2.1 20191109 (Debian 9.2.1-19)). Здесь нет отладчика.

Затем в бесконечном l oop функции изменения метки качества и значения сигнала на сервере вызываются одна за другой. Реализация функций практически одинакова. Разница в том, что SetBadQuality работает для нескольких значений одновременно, а ChangeValue работает для одного указанного c сигнала.

Модифицированные сигналы (не имеет значения, изменились ли метка качества или значение) в очередь (CS104_Slave_enqueueASDU), после чего клиент получает данные из этой очереди. Библиотека говорит, что когда очередь заполнена, они начинают перезаписывать старые значения в этой очереди. И как только клиент получает данные из очереди, они удаляются в очереди. Для отправки данных клиенту используются пакеты ASDU (Application Data Data Unit) в TSP / IP.

Сначала программа работает правильно. Клиент успешно принимает измененные значения сигнала. Их качество меняется, их ценности меняются. Все работает хорошо.

Но в определенный момент времени вылетает segFault. Ошибка вылетает только тогда, когда клиент подключен к серверу. Если клиент не подключен к серверу, то программа работает правильно без ошибок (но ошибка сегмента появляется сразу после подключения клиента к серверу).

Использовал утилиту valgrind для генерации сообщений журнала.

На самом деле углубленное изучение этой библиотеки не требуется. Может кто-нибудь сказать мне, что моя ошибка конкретно в C ++? Почему ошибка сегмента cra sh?

Если я изменю число элементов в списке (например, с 450 до 500), ошибка появится в другой момент времени.

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
    }
}

Мне пришлось удалить те же самые куски журналов valgrind, потому что я должен был встретить ограничение в 30000 символов в тексте. Удалил логи с разных сайтов. Поэтому не бойтесь, что где-то может произойти разрыв в логической цепочке. Я пытался оставить точку и удалить только те же разделы текста. При необходимости могу выслать полный текст логов!

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

1 Ответ

0 голосов
/ 03 апреля 2020

Вам нужно go пройти через ошибки одну за другой и исправить их. Возьмите первую ошибку

==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==  Address 0x4b5b0b8 is 0 bytes after a block of size 13,600 alloc'd

Это дает адрес блока памяти, который не очень используется. В нем также говорится, что длина блока составляет 13600 байт, и что ваш недопустимый доступ является первым байтом после этого блока.

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

Это функция, которую Valgrind использовал для замены calloc, чтобы Valgrind мог отслеживать память распределение. Вы можете игнорировать эту строку.

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

Это похоже на вашу обертку вокруг calloc. Опять же, вы, вероятно, можете игнорировать это.

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

Это то место, где вы действительно просите память. Вы должны посмотреть здесь, чтобы проверить, не сделали ли вы ошибку и должны ли вы выделять здесь больше памяти. Лично я подозреваю, что это не так.

Теперь давайте посмотрим на первый блок.

==3374== Invalid read of size 1

Это говорит о том, что недопустимая операция выполняется с одним байтом. Таким образом, это означает, что основным типом, вызывающим недопустимую операцию, является char или bool (char с учетом следующих частей с ошибкой).

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

Опять же, это функция замены при условии Вальгриндом. Вы можете игнорировать это.

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

Теперь, вероятно, именно в этом и заключается настоящая ошибка.

Двумя распространенными причинами такого рода ошибок являются

  1. Выдается на одну ошибку в al oop
    Например, в псевдокоде
// 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]
Строковая операция, в которой пропущен завершающий nul символ
Снова пример psuedocode
// 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);
...