Reputation: 97
I am making a program that serialize a struct of data and send it to the server. The problems come to when the function that serialize fails when it has been use, more or less 40 times or so.
I am using Visual Studio Community 2015, boost 1.59 32bits and winsock2, the program is compiled with 32 bits architecture.
The error is:
Exception produced in 0x772BE3C6 (ntdll.dll) in Test.exe: 0xC0000005: Access violation reading the location 0x3838E1A9.
And here is a simple example using the function that crash:
#define WIN32_LEAN_AND_MEAN
#include <WinSock2.h>
#include <WS2tcpip.h>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/iostreams/device/back_inserter.hpp>
#include <boost/iostreams/device/array.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/iostreams/stream.hpp>
struct StructFunction
{
char function;
int arguments;
template<class Archive>
void serialize(Archive &ar, const unsigned int version)
{
ar & function;
ar & arguments;
}
};
BOOST_CLASS_IMPLEMENTATION(StructFunction, boost::serialization::object_serializable)
bool Send(std::string buffer)
{
int iResult = send(ConnectSocket, buffer.data(), buffer.size(), 0);
if(iResult == SOCKET_ERROR)
{
printf("send failed: %d\n", WSAGetLastError());
Stop();
return false;
}
return true;
}
int SerializeAndSend(StructFunction structFunction)
{
// serialize obj into an std::string
std::string serial_str;
serial_str.clear();
boost::iostreams::back_insert_device<std::string> inserter(serial_str);
boost::iostreams::stream<boost::iostreams::back_insert_device<std::string> >
s(inserter);
boost::archive::binary_oarchive oa(s); // This throws the error
oa << structFunction;
// flush the stream to finish writing into the buffer
s.flush();
Send(serial_str);
return 1;
}
int main(int argc, char* argv[])
{
ConnectSocket = /* We create a socket that is connected to the server using winsock2 */
StructFunction structFunction;
structFunction.function = "A";
structFunction.parameter = 1;
SerializeAndSend(structFunction);
}
In the real code the function SerializeAndSend is called 40 times aprox.
I can say, 90% for sure, that the serialized struct is initialized and did not had any wrong value.
I have try to clean the projects in the client and the server. The RAM they use is very low, 13mb more or less.
I do not know why it fails when it has been use and not in the first time.
Upvotes: 3
Views: 856
Reputation: 393134
The idea of eliminating causes, is to make the thing very self-contained and just observe whether it still reproduces the/a problem:
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/iostreams/device/back_inserter.hpp>
#include <boost/iostreams/device/array.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/iostreams/stream.hpp>
struct StructFunction
{
char function;
int arguments;
template<class Archive>
void serialize(Archive &ar, const unsigned int version)
{
ar & function;
ar & arguments;
}
};
BOOST_CLASS_IMPLEMENTATION(StructFunction, boost::serialization::object_serializable)
bool Send(std::string buffer)
{
/*
* int iResult = send(ConnectSocket, buffer.data(), buffer.size(), 0);
*
* if(iResult == SOCKET_ERROR)
* {
* printf("send failed: %d\n", WSAGetLastError());
* Stop();
* return false;
* }
*/
return true;
}
int SerializeAndSend(StructFunction structFunction)
{
// serialize obj into an std::string
std::string serial_str;
namespace bio = boost::iostreams;
{
bio::stream<bio::back_insert_device<std::string> > s(serial_str);
boost::archive::binary_oarchive oa(s);
oa << structFunction;
}
static bool do_init = true;
if (do_init) {
std::cout << "DEBUG: \n";
for (uint8_t ch : serial_str)
std::cout << std::setw(2) << std::setfill('0') << std::showbase << std::hex << static_cast<int>(ch) << " ";
do_init = false;
}
Send(serial_str);
return 1;
}
int main()
{
//ConnectSocket = [> We create a socket that is connected to the server using winsock2 <]
for (auto i = 0ull; i< 1ull << 22; ++i) {
StructFunction structFunction;
structFunction.function = 'A';
structFunction.arguments = 1;
SerializeAndSend(structFunction);
}
}
As you can see, not a lot of trouble, output:
DEBUG:
0x16 00 00 00 00 00 00 00 0x73 0x65 0x72 0x69 0x61 0x6c 0x69 0x7a 0x61 0x74 0x69 0x6f 0x6e 0x3a 0x3a 0x61 0x72 0x63 0x68 0x69 0x76 0x65 0xd 00 0x4 0x8 0x4 0x8 0x1 00 00 00 0x41 0x1 00 00 00
real 0m24.026s
user 0m24.010s
sys 0m0.000s
Try it on your system. If it's ok, then the problem is in Send
(and related functions).
If you see the problem on your platform, consider (memory) profiling and enabling the debug heap for diagnostics.
Upvotes: 2