我的服务器出现分段故障(valgrind日志)



有一个问题,我已经开车三个多星期了。请帮忙提建议。我非常恳求你!我是C++新手。即使是小提示也能帮助我!

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

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

我使用了一个现成的库,用C语言实现了IEC-104协议,并创建了一个C++程序。(GIT链接(

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

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

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

起初,程序工作正常。客户端成功接受更改后的信号值。他们的品质在改变,他们的价值观在改变​​正在发生变化。一切都很好。

但某个时间点过得很快。只有当客户端连接到服务器时,错误才会崩溃。如果客户端未连接到服务器,则程序正常工作,没有错误(但在客户端连接到服务器后立即出现seg错误(。

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

事实上,不需要对这个图书馆进行深入研究。有人能告诉我我在C++中的错误是什么吗?seg故障为什么会崩溃?

如果我更改列表中的元素数量(例如,从450个元素更改为500个(,则错误会出现在另一个时间点。

IEC104服务器.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 createdn");
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 intn");
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 createdn");
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 Mapn");
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 createdn");
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 createdn");    
int value = 0;
while(true)
{
printf ("start bad quiality functionn");
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 successfuln");
}   
printf ("start change value functionn");
// 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 successfuln");
}
value++;
if (value == 10000)
{
printf ("null valuen");
value = 0;
}
usleep(100000);  //pause 0.1 second
}
usleep(100000); //pause 0.1 second
}
}

我不得不删除相同的valgrind日志,因为我必须满足文本中30000个字符的限制。已从不同站点删除日志。因此,不要害怕某个地方可能会出现逻辑链断裂。我试着离开重点,只删除文本中相同的部分。如果需要,我可以发送日志的全文

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

这就给出了内存块的地址,这并没有多大用处。它还说,该块长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

这意味着无效操作在一个字节上。因此,这意味着导致无效操作的基本类型是charbool(考虑到错误的以下部分的char(。

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

同样,这是Valgrind提供的替代功能。你可以忽略这一点。

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

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

造成这种错误的两个常见原因是

  1. 循环中一个错误退出
    例如,在伪代码中
// 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. 省略尾部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);

最新更新