gpt4 book ai didi

c++ - 我的服务器中的段错误(valgrind 日志)

转载 作者:行者123 更新时间:2023-12-02 10:34:36 24 4
gpt4 key购买 nike

有一个问题我已经开车超过 3 周了。请帮忙提供建议。我非常求求你!我是 C++ 新手。即使是小技巧也可以帮助我!

需要创建一个必须存储各种信号的整数值的服务器。客户端可以连接到此服务器并接收此数据。

客户端和服务器之间的数据传输根据工业协议(protocol) IEC-60870-5-104 TCP/IP 进行。

我使用了一个现成的库,它在 C 中实现了这个 IEC-104 协议(protocol),并创建了一个 C++ 程序。 (GIT link)

我写了一个测试程序(main.cpp)。具有值的信号列表(例如,450 个元素)到达输入,然后将该列表传输到 Map 字典。该程序从命令行在Linux Debian上编译运行(gcc版本9.2.1 20191109(Debian 9.2.1-19)
)。这里没有调试器。

然后,在一个无限循环中,服务器上改变质量标签和信号值的函数被一一调用。功能的实现几乎相同。不同之处在于 SetBadQuality 一次对多个值起作用,而 ChangeValue 对一个特定信号起作用。

修改后的信号(无论质量标签或值是否已更改)被添加到队列(CS104_Slave_enqueueASDU),之后客户端从该队列接收数据。该库表示,当队列已满时,它们开始覆盖此队列中较旧的值。并且一旦客户端从队列中接收到数据,它们就会在队列中被删除。为了向客户端发送数据,使用了 TSP/IP 中的 ASDU(应用服务数据单元)数据包。

起初,该程序运行正常。客户端成功接受更改的信号值。他们的品质在变,他们的值(value)观在变。一切正常。

但是某个时间点过segFault。仅当客户端连接到服务器时,该错误才会崩溃。如果客户端没有连接到服务器,那么程序可以正常工作而没有错误(但是客户端连接到服务器后立即出现seg fault)。

使用 valgrind 实用程序生成日志消息。

事实上,不需要深入研究这个库。有人可以告诉我我的错误在 C++ 中具体是什么吗?为什么段故障会崩溃?

如果我更改 List 中的元素数量(例如,从 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);

};

简单服务器.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;
}

主文件
#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 日志,因为我必须满足文本中 30,000 个字符的限制。已从不同站点删除日志。因此,不要担心逻辑链的某个地方可能会中断。我试图离开这一点,只删除文本的相同部分。如果需要,我可以发送日志的全文!

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

最佳答案

您需要一一检查错误并修复它们。取第一个错误

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

这给出了内存块的地址,没有多大用处。它还说该 block 的长度为 13600 字节,并且您的无效访问是该 block 之后的第一个字节。
==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)

这是你真正要求内存的地方。您需要查看此处以检查您是否没有犯错,并且您应该在此处分配更多内存。我个人怀疑情况并非如此。

现在让我们看看第一个 block 。
==3374== Invalid read of size 1

这就是说无效操作在一个字节上。所以这意味着导致无效操作的基本类型是 charbool ( char 考虑到错误的以下部分)。
==3374==    at 0x4845704: memcpy (vg_replace_strmem.c:1036)

同样,这是 Valgrind 提供的替换功能。你可以忽略这个。
==3374==    by 0x116063: MessageQueue_getNextWaitingASDU (cs104_slave.c:332)

现在这很可能是真正的错误所在。

这种错误的两个常见原因是
  • 循环中出现一个错误
    例如,在伪代码
  • // 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 的字符串操作特点
    又是一个伪代码示例
  • // 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);

    关于c++ - 我的服务器中的段错误(valgrind 日志),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60960363/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com