简体   繁体   English

我的服务器中的分段错误(valgrind 日志)

[英]Segmentation fault in my server (valgrind logs)

There is a problem that I've been driving with for more than 3 weeks.有一个问题,我已经驾驶了 3 个多星期。 Please help with advice.请帮助提供建议。 I beg you very much!我非常恳求你! I am new to C ++.我是 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.客户端和服务器之间的数据传输根据工业协议 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.我使用了一个现成的库,它在 C 中实现了这个 IEC-104 协议并创建了一个 C++ 程序。 ( GIT link ) ( GIT 链接)

I wrote a test program (main.cpp).我写了一个测试程序(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.具有值的信号列表(例如,450 个元素)到达输入,然后将此列表传输到 Map 字典。 The program compiles and runs on Linux Debian from the command line (gcc version 9.2.1 20191109 (Debian 9.2.1-19) ).该程序从命令行编译并在 Linux Debian 上运行(gcc 版本 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.不同之处在于 SetBadQuality 一次作用于多个值,而 ChangeValue 作用于一个特定信号。

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.修改后的信号(质量标签或值是否发生变化无关紧要)被添加到队列(CS104_Slave_enqueueASDU)中,之后客户端从该队列接收数据。 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.为了向客户端发送数据,使用了 TSP/IP 中的 ASDU(应用服务数据单元)数据包。

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.但是在某个时间点过时了 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).如果客户端没有连接到服务器,那么程序可以正常运行,没有错误(但是客户端连接到服务器后立即出现seg错误)。

Used the valgrind utility to generate log messages.使用 valgrind 实用程序生成日志消息。

In fact, no in-depth study of this library is required.事实上,不需要深入研究这个库。 Can someone tell me what my error is specifically in C ++?有人能告诉我我在 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.如果我更改 List 中的元素数量(例如,从 450 个元素更改为 500 个),错误会出现在另一个时间点。

IEC104Server.h 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 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.我不得不删除相同的 valgrind 日志,因为我必须满足文本中 30,000 个字符的限制。 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 valgrind 日志

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.它还说该块长 13600 字节,并且您的无效访问是该块之后的第一个字节。

==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.这是 Valgrind 用来替换calloc的函数,以便 Valgrind 可以跟踪内存分配。 You can ignore this line.您可以忽略此行。

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

This looks like your wrapper around calloc .这看起来像你对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).所以这意味着导致无效操作的基本类型是charboolchar考虑到错误的以下部分)。

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

Again, this is a replacement function provided by Valgrind.同样,这是 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省略尾随nul字符的字符串操作
    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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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