Access violation reading location. Heap corruption. Boost thread - c++

I'm trying to create an multithreaded graphical network application using boost, raknet and irrlicht.
I use one thread that receives messages and another thread to proccess the messages and all the graphical work.
this is the error screen I'm getting
First-chance exception at 0x77183c8d in
NetSystemForVideogamesServerTester.exe: 0xC0000005: Access violation reading location 0x0d99d472
this is the output window information
HEAP[NetSystemForVideogamesServerTester.exe]: HEAP: Free Heap block
da58d10 modified at da58fe0 after it was freed Windows has triggered a
breakpoint in NetSystemForVideogamesServerTester.exe.
This may be due to a corruption of the heap, which indicates a bug in
NetSystemForVideogamesServerTester.exe or any of the DLLs it has
loaded.
This may also be due to the user pressing F12 while
NetSystemForVideogamesServerTester.exe has focus.
The output window may have more diagnostic information.
this is when I launch the thread
void receive()
{
boost::thread(&IConnectionInstance::receiveInThread, this);
}
mutex declaration
boost::mutex mMessagesReceived;
this is the code from the receiving thread
void RakNetConnectionInstance::receiveInThread()
{
Packet* packet;
IMessage* message = NULL;
long time = 0;
while (true)
{
message = NULL;
packet = aPeer->Receive();
while (packet)
{
RakNet::BitStream* dataStream = new RakNet::BitStream(packet->data, packet->length, false);
dataStream->IgnoreBits(sizeof(unsigned char)*8);
switch (packet->data[0])
{
case ID_TIMESTAMP:
{
dataStream->Read(time);
int countMessagesAggregated = 0;
dataStream->Read(countMessagesAggregated);
unsigned char messageType = char();
IBitStream* bitStream = new RakNetBitStream(dataStream);
while(countMessagesAggregated > 0)
{
dataStream->Read(messageType);
switch ((EMESSAGE_TYPE)messageType)
{
case EACTOR_CONTENT_MESSAGE:
message = new CActorContentMessage(aUserDataFactory);
break;
case EWORLD_CONTENT_MESSAGE:
message = new CWorldClientContentMessage(aUserDataFactory);
break;
case EUSER_COMMAND_MESSAGE:
message = new CUserCommandMessage(aEventFactory);
break;
case EPREDICTION_MESSAGE:
message = new CPredictionMessage(aUserDataFactory);
break;
case EPREDICTION_RESPONSE_MESSAGE:
message = new CPredictionResponseMessage(aUserDataFactory);
break;
}
countMessagesAggregated --;
if (messageType >= EUSER_MESSAGE && aCustomReceiver)
{
aCustomReceiver->receiveCustomMessages();
}
if (message)
{
message->readFromBitStream(bitStream);
message->setTimeMS(time);
message->setIPAddress(packet->systemAddress.ToString(false));
message->setPort(packet->systemAddress.port);
mMessagesReceived.lock();
aMessagesReceivedQueue.push(message);
printf("adicionando mensaje a cola en lock\n");
mMessagesReceived.unlock();
message = NULL;
}
}
}
break;
}
if (message)
{
message->setTimeMS(time);
message->setIPAddress(packet->systemAddress.ToString(false));
message->setPort(packet->systemAddress.port);
mMessagesReceived.lock();
aMessagesReceivedQueue.push(message);
mMessagesReceived.unlock();
}
aPeer->DeallocatePacket(packet);
packet = aPeer->Receive();
}
if (RakNet::GetTimeMS() - aBeginTimeSearchServersActives > aWaitTimeServersActives && !aTimeOut)
{
boost::mutex::scoped_lock lock(mTimeOut);
aTimeOut = true;
}
}
}
here I attend the messages from queue in the proccessing thread
void CMessageManager::attendMessages()
{
std::queue<IMessage*> messages = aConnectionInstance->getMessagesReceivedFromQueue();
while(!messages.empty())
{
notifyMessage(messages.back());
aConnectionInstance->popMessageReceivedFromQueue();
messages.pop();
}
}
here I access the message queue
std::queue<IMessage*> RakNetConnectionInstance::getMessagesReceivedFromQueue()
{
boost::mutex::scoped_lock lock(mMessagesReceived);
std::queue<IMessage*> messages;
messages = aMessagesReceivedQueue;
return messages;
}
and finally here I delete the message from queue
void RakNetConnectionInstance::popMessageReceivedFromQueue()
{
boost::mutex::scoped_lock lock(mMessagesReceived);
if (!aMessagesReceivedQueue.empty())
{
aMessagesReceivedQueue.pop();
}
}
I'm new to c++ and multithreading, Please help me, What am I doing wrong?
Thanks in advance.

You don't remove the messages from the original queue, you just copy the pointers to a new queue. So the following happens:
You receive a message. A pointer to it goes on the queue.
You copy the queue, process the message, and delete it.
You receive another message.
You copy the queue. It still contains a pointer to the first message though.
You access the pointer to the first message that you deleted.
This code is broken because it copies the queue leaving the original unmodified:
std::queue<IMessage*> RakNetConnectionInstance::getMessagesReceivedFromQueue()
{
boost::mutex::scoped_lock lock(mMessagesReceived);
std::queue<IMessage*> messages;
messages = aMessagesReceivedQueue;
return messages;
}

Related

Why I can't receive next messages without deleting previous in SQS queue using c++

I have the following example, where I'm trying to receive messages from SQS queue.
I can successfully get first batch of messages, but after that, the function ReceiveMessage() returns only an empty messages.
If I delete all received messages after every call of ReceiveMessage() I can see next messages.
So I want to know why?
Because as I understand after receiving messages, they are going to in-flight mod,
so when I call ReceiveMessage() again, I should get the next batch of messages without calling delete
Thank You
Aws::Vector<Aws::SQS::Model::Message> receive_message() const
{
Aws::SQS::Model::ReceiveMessageRequest rm_req;
rm_req.SetQueueUrl(queue_url_);
rm_req.SetMaxNumberOfMessages(10);
rm_req.SetWaitTimeSeconds(20);
const Aws::SQS::Model::ReceiveMessageOutcome rm_out = sqs_client_->ReceiveMessage(rm_req);
if (false == rm_out.IsSuccess())
{
throw;
}
Aws::Vector<Aws::SQS::Model::Message> messages = rm_out.GetResult().GetMessages();
return messages;
}
int main()
{
AmazonSQSReceiver sqs_receiver(Global::queue_name);
while (true)
{
Aws::Vector<Aws::SQS::Model::Message> messages = sqs_receiver.receive_message();
for (const auto &message : messages)
{
const Aws::String &message_body = message.GetBody();
std::cout<< message_body << std::endl;
}
}
return 0;
}

C++ GRPC Async Bidirectional Streaming - How to tell when a client sent a message?

There is zero documentation how to do an async bidirectional stream with grpc. I've made guesses by piecing together the regular async examples with what I found in peope's github.
With the frankestein code I have, I cannot figure out how to tell when a client sent me a message. Here is the procedure I have running on its own thread.
void GrpcStreamingServerImpl::listeningThreadProc()
{
try
{
// I think we make a call to the RPC method and wait for others to stream to it?
::grpc::ServerContext context;
void * ourOneAndOnlyTag = reinterpret_cast<void *>(1); ///< Identifies the call we are going to make. I assume we can only handle one client
::grpc::ServerAsyncReaderWriter<mycompanynamespace::OutputMessage,
mycompanynamespace::InputMessage>
stream(&context);
m_service.RequestMessageStream(&context, &stream, m_completionQueue.get(), m_completionQueue.get(), ourOneAndOnlyTag);
// Now I'm going to loop and get events from the completion queue
bool keepGoing = false;
do
{
void* tag = nullptr;
bool ok = false;
const std::chrono::time_point<std::chrono::system_clock> deadline(std::chrono::system_clock::now() +
std::chrono::seconds(1));
grpc::CompletionQueue::NextStatus nextStatus = m_completionQueue->AsyncNext(&tag, &ok, deadline);
switch(nextStatus)
{
case grpc::CompletionQueue::NextStatus::TIMEOUT:
{
keepGoing = true;
break;
}
case grpc::CompletionQueue::NextStatus::GOT_EVENT:
{
keepGoing = true;
if(ok)
{
// This seems to get called if a client connects
// It does not get called if we didn't call 'RequestMessageStream' before the loop started
// TODO - How do we tell when the client send us a messages?
// TODO - How do we know if they are just connecting?
// TODO - How do we get the message client sent?
// The tag corresponds to the request we made
if(tag == reinterpret_cast<void *>(1))
{
// SNIP successful writing of a message
stream.Write(*(outputMessage.get()), reinterpret_cast<void*>(2));
}
else if(tag == reinterpret_cast<void *>(2))
{
// This is telling us the message we sent was completed
}
else
{
// TODO - I dunno what else it can be
}
}
break;
}
case grpc::CompletionQueue::NextStatus::SHUTDOWN:
{
keepGoing = false;
break;
}
}
} while(keepGoing);
// Completion queue was shutdown
}
catch(std::exception& e)
{
QString errorMessage(
QString("An std::exception was caught in the listening thread. Exception message: %1").arg(e.what()));
m_backPointer->onImplError(errorMessage);
}
catch(...)
{
QString errorMessage("An exception of unknown type, was caught in the listening thread.");
m_backPointer->onImplError(errorMessage);
}
}
Setup looked like this
// Start up the grpc service
grpc::ServerBuilder builder;
builder.RegisterService(&m_service);
builder.AddListeningPort(endpoint.toStdString(), grpc::InsecureServerCredentials());
m_completionQueue = builder.AddCompletionQueue();
m_server = builder.BuildAndStart();
// Start the listening thread
m_listeningThread = QThread::create(&GrpcStreamingServerImpl::listeningThreadProc, this);

POCO C++ Getting only one notification when socket is readable?

I now writing game server and here is my onReadable function :
void CSConnection::onReadable(const AutoPtr<ReadableNotification>& pNf)
{
try
{
char * rbuff = new char[128](); //allocate incoming packet memory
int n = _socket.receiveBytes(rbuff, 128);
if(n > 8)
{
WorkerThreadPool::getInstance().tp->start(*new LogicHandler(*this, rbuff));
}
else
{
delete rbuff;
delete this;
}
}
catch(Poco::Exception& exc)
{
app.logger().log(exc);
delete this;
}
}
I tried to move reading packet in thread pool's logic handler, but notification is called multiply.
Is there a way to get only one notification ?
Because reading in thread is slower and it calls 5-9 times onReadable.
Thanks.

WinHttp used in async mode - ERROR_INTERNET_CANNOT_CONNECT how to cleanly close connection

I get lots of ERROR_INTERNET_CANNOT_CONNECT (12029 code) in callback procedure of the request.
I use WinHttp in async mode(on a server). How do you cleanly close the connection in this case. Do you just use something like this(like you normally close a connection?):
::WinHttpSetStatusCallback(handle, NULL, 0, 0);
::WinHttpCloseHandle(this->handle));
I ask this because I have some strange memory leaking associated with winhttp dll that occurs in the situation described(want to create hundreds of concurrent connections that are probably blocked by the firm internal firewall or destination server drops the connections). I have already looked at the documentation of WinHttpCloseHandle on msdn...
Here is how I do handling of the callback states:
template <typename T>
void WinHttp::AsyncRequest<T>::OnCallback(DWORD code, const void* info, DWORD length)
{
T* pT = static_cast<T*>(this);
switch (code)
{
case WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE:
case WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE:
{
HRESULT result = pT->OnWriteData();
if (FAILED(result))
{
throw CommunicationException(::GetLastError());
}
if (S_FALSE == result)
{
if (!::WinHttpReceiveResponse(handle, 0)) // reserved
{
throw CommunicationException(::GetLastError());
}
}
break;
}
case WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE:
{
DWORD statusCode;
DWORD statusCodeSize = sizeof(DWORD);
if (!::WinHttpQueryHeaders(handle, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, WINHTTP_HEADER_NAME_BY_INDEX, &statusCode, &statusCodeSize, WINHTTP_NO_HEADER_INDEX))
{
throw CommunicationException(::GetLastError());
}
pT->OnStatusCodeReceived(statusCode);
if (!::WinHttpQueryDataAvailable(handle, 0))
{
// If a synchronous error occured, throw error. Otherwise
// the query is successful or asynchronous.
throw CommunicationException(::GetLastError());
}
break;
}
case WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE:
{
unsigned int size = *((LPDWORD) info);
if (size == 0)
{
pT->OnResponseComplete(S_OK);
}
else
{
unsigned int sizeToRead = (size <= chunkSize) ? size : chunkSize;
if (!::WinHttpReadData(handle, &buffer[0], sizeToRead, 0)) // async result
{
throw CommunicationException(::GetLastError());
}
}
break;
}
case WINHTTP_CALLBACK_STATUS_READ_COMPLETE:
{
if (length != 0)
{
pT->OnReadComplete(&buffer[0], length);
if (!::WinHttpQueryDataAvailable(handle, 0))
{
// If a synchronous error occured, throw error. Otherwise
// the query is successful or asynchronous.
throw CommunicationException(::GetLastError());
}
}
else
{
pT->OnResponseComplete(S_OK);
}
break;
}
case WINHTTP_CALLBACK_STATUS_REQUEST_ERROR:
{
{
throw CommunicationException(::GetLastError());
}
break;
}
}
}
Here buffer is a vector that has reserved 8K once the request is initiated. Thanks in advance.
In OnResponseComplete, OnResponsEerror I eventually call also:
::WinHttpSetStatusCallback(handle, NULL, 0, 0);
assert(::WinHttpCloseHandle(this->handle));
this->handle = nullptr;
Roman R was right about the issue just want to include more details in the response.
Cancellation is tricky. For WinHTTP you need to remember that callbacks fire on a thread pool. They can arrive on a random thread and since the thread pool does not guarantee when the callback is executed, you could call WinHttpSetStatusCallback to clear the callback and then later on still receive callbacks. You thus need to synchronize this yourself. A more subtle problem is that you cannot call back into WinHTTP from a callback. The safest and most reliable way to handle WinHTTP callbacks is to dispatch the callbacks to a single thread. This could be a UI thread or a single-threaded thread pool. You then also need to close the handle first and then wait for the callback to indicate that the handle is closed (WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING) – only then is it safe to release any connection-specific resources, callbacks, etc.
My tests so far showed that closing the request handle must be done outside the callbacks and also the final closing of the connection handle. One can queue up the intent to close the request and afterwards the connection closing and other cleanup on a separate thread using QueueUserApc so that at least those 2 operations are synchronized.
EDIT
The problem still remains. What I wrote below did not fix the issue.
The problem described was actually not very much related to ERROR_CANNOT_CONNECT but to the way I was "incorectly" handling the async status callback notifications of winhttp. If anyone would be interested I will copy here a typical way of handling the status notifications.

boost::io_service, threads and std::set

If there is something more difficult than debugging a multithreaded app that is trying to describe the bug itself.
I have two boost::threads (application and display).
Both use the same asio::io_service to do their work.
The display thread has a std::set of type window* which is a class I use to wrap winapi window management.
I use a custom message queue to communicate these two threads.
One of these messages (terminate) is used to notify the display thread that it must not "post" any more methods and that it must call thread_group.remove_thread and remove itself.
The thread has a variable (state) that flags the state of the thread (running, paused, terminated).
If it is running it "posts" it's update() method that iterates an std::set and calls the update method in each window* it contains.
If it is terminated, it clears the std::set, removes itself from the thread_group and doesn't post any more work.
The problem: Once a while, when trying to close the app, the thread's update method gets ran after the thread got "terminated" and the std::set got cleared. Then the update method tries to iterate the std::set and a SIGSEGV takes place. This only happens 1 every 10 runs of the application and I'm having a hard time trying to guess what's wrong.
I'll try to post the relevant code, if more is needed I'll try to add it.
int main(int argc, char **argv)
{
boost::asio::io_service ios;
boost::asio::strand strand(ios);
boost::thread_group threads;
owl::system::pump pump;
application app(&threads, &strand, &pump);
owl::system::display display(&strand, &pump);
ios.run();
threads.join_all();
return 0;
}
...
void display::on_terminate()
{
close_all_windows();
}
...
void display::close_all_windows()
{
windows.move_first();
while (!windows.eof())
{
window* win = windows.value();
win->destroy();
delete win;
windows.move_next();
}
windows.clear();
check_no_window();
}
...
void display::on_update()
{
if (windows.size())
{
windows.move_first();
while (!windows.eof())
{
windows.value()->update();
windows.move_next(); // Here happens the SIGSEGV
}
}
}
The class display inherits the class subsystem that manages thread execution. This is the relevant code involving the execution of on_update()
void subsystem::do_update()
{
message* msg;
size_t message_count = messages.size();
for (size_t i=0; i<message_count; i++)
{
msg = messages[i];
process_message(msg);
strand->dispatch(strand->wrap(boost::bind(&message::deallocate, msg)));
}
switch (state)
{
case running:
{
on_update();
}
break;
case paused:
{
// Do not update. Just check the queue and sleep
sleep(10);
}
break;
case terminated:
{
do_terminate();
return;
}
break;
}
strand->post(strand->wrap(boost::bind(&subsystem::check_for_messages, this)));
}
void subsystem::check_for_messages()
{
messages.clear();
pump->get_messages(this, messages);
ios->post(boost::bind(&subsystem::do_update, this));
}
The SIGSEGV occurs exactly when trying to increment the std::set iterator.
Child process PID: 2272
Program received signal SIGSEGV, Segmentation fault.
In std::_Rb_tree_increment(std::_Rb_tree_node_base const*) ()
stl_tree.h:269