I'm reading read/write configuration for plc from database and storing them in an std::unordered_map.
Whenever, I attempt to insert the extracted record in the std::unordered_map I get an exception. Analyzing variable before insert statement shows data is available with the variables.
I am unable to understand why the exception is thrown at 0x00007FFC0C05BD82 (snap7.dll) in SeimensPLC.exe.
Code :
//plc_ip tuple(plc_client_object read_vector write_vector)
std::unordered_map<std::string, plc_common::plc_config_data_tuple> plc_;
std::optional<TS7Client> plc::connect_plc(const std::string& ip, std::uint8_t connectionType, std::uint16_t rack, std::uint16_t slot)
{
TS7Client client;
client.SetConnectionType(connectionType); //PG-PC : Programming Console type connection
if (client.ConnectTo(ip.c_str(), rack, slot) not_eq EXIT_SUCCESS)
return std::nullopt;
return client;
}
bool plc::add_plc(const std::string& ip, const std::vector<config_table_struct>& config_list)
{
try
{
std::optional<TS7Client> client = this->connect_plc(ip);
if (not client.has_value())
{
std::string strErr = fmt::format("Unable to connect to plc : {}", ip);
LOG_ERROR << strErr;
return false;
}
plc_common::read_vector read_vector;
plc_common::write_vector write_vector;
std::for_each(config_list.begin(), config_list.end(), [&](const config_table_struct& config_struct) {
plc_common::config_struct config;
config.serial_no = config_struct.serial_no;
config.area_number = config_struct.area_number;
config.read_location = config_struct.read_location;
config.read_length = config_struct.read_length;
config.scan_rate = config_struct.scan_rate;
config.data_type = config_struct.data_type;
config.area_type = 0x84;
config.data_queue = plc_common::data_queue{};
read_vector.push_back(config);
});
plc_common::plc_config_data_tuple plc_config_data_tuple = std::make_tuple(client.value(), read_vector, write_vector);
this->plc_.insert(std::make_pair(ip, plc_config_data_tuple)); //Executing this statement gives exception
return true;
}
catch (const std::exception& ex)
{
LOG_FATAL << "Exception : " << ex.what();
}
return false;
}
Exception :
Exception thrown at 0x00007FFC0C05BD82 (snap7.dll) in SeimensPLC.exe: 0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFF04.
Unhandled exception at 0x00007FFC0C05BD82 (snap7.dll) in SeimensPLC.exe: 0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFF04.
Edit :
As requested I have added all typedefs.
typedef std::variant<bool, std::uint8_t, std::int16_t, std::int32_t, std::uint16_t, std::uint32_t, std::float_t, char> plc_data_type;
typedef std::queue<plc_common::plc_data_type> data_queue;
typedef struct {
std::uint32_t serial_no;
std::uint8_t area_type;
std::uint8_t area_number;
std::uint16_t read_location;
std::uint16_t read_length;
std::string data_type;
std::uint32_t scan_rate;
plc_common::data_queue data_queue;
} config_struct;
//read_vector/write_vector area_type area_number read/write_location read/write_size scanRate read/write_queue
typedef std::vector<plc_common::config_struct> read_vector, write_vector;
// s7_socket vector storing read/write information
typedef std::tuple<TS7Client, plc_common::read_vector, plc_common::write_vector> plc_config_data_tuple;
I am unable to understand why the exception is thrown at 0x00007FFC0C05BD82
You should be aware that this is not C++ exception is thrown, but access violation is raised by hardware with memory protection. There could be a lot of reasons of this. One of the most often reason is invoking Undefined Behavior somewhere in the code with subsequent memory corruption or access of the memory which should not normally be accessed.
As for how to debug, you can use Dr. Memory on Windows or Valgrind, if you were on Linux.
User contributions licensed under CC BY-SA 3.0