alanxz / SimpleAmqpClient

Simple C++ Interface to rabbitmq-c
MIT License
397 stars 213 forks source link

Debug assertions after messages are consumed #160

Open Erik-Peet opened 7 years ago

Erik-Peet commented 7 years ago

Hi,

We have integrated your library into our C++ solutions to communicate with our AMQP server.

The problem we are having is popping up when we are building for the Debug target. Our C++ code then consumes a message and we handle it accordingly, but after our code is done our application always crashes with a "_BLOCK_TYPE_IS_VALID(pHead->nBlockUse)" assertion error.

This always happens after a message is consumed, received and handled. And only when we are running in Debug mode. When we build everything for target Release(Debug) we never see this assert and can communicate via AMQP perfectly. Our application is build with Visual Studio 2013 and runs on a Windows 10 system.

Our main questions are: Have you perhaps seen such an assertion error before? Can it perhaps be that an internally kept list, pointer or reference is emptied/deleted in the library code which triggers this assertion?

alanxz commented 7 years ago

I have not seen this particular assertion before, it appears to be something that MSVC enables in debug builds in the memory-management routines (think malloc or free).

Is it possible to obtain a stack-trace of where this is happening, and a pared down example that triggers the assertion?

Erik-Peet commented 7 years ago

Hi Alan,

Thanks yo for the quick reply. Unfortunately we do not have any stack trace for the exact point of the crash. But the code we have to setup the connection and consume messages is as follows:

We run the AMQP message consuming in an CIdleTask class which has a runTask method which we run every few seconds. When we enable the idle task to run we first setup a connection. We do this via a member var fConnection which holds either a secure or a regular connection.

fConnection = AmqpClient::Channel::CreateSecure(...)

fConnection = AmqpClient::Channel::Create(...)

After that, if the connection is established we will try to consume a message.

if(fConnection)
    fConsumer_tag = fConnection->BasicConsume(...)

After that, the runTask of the idleTask runs every few seconds and will check for messages to consume via the following code:

try { // Check if there is a message that can be consumed. AmqpClient::Envelope::ptr_t envelope; if( !fConnection->BasicConsumeMessage(fConsumer_tag, envelope, 0) ) break;

AmqpClient::BasicMessage::ptr_t message = envelope->Message();
if( !message )
    break;

bMessageReceived = kTrue;

this->HandleMessage( message->Body() );

} catch() {}

This code does not crash, though. It is only after the runTask method is going out of scope that the crash happens. Unfortunately, we tried to get the stack trace up to the crash to no avail.

alanxz commented 7 years ago

Is it possible to create a minimal example that consistently triggers the crash?

Erik-Peet commented 7 years ago

I tried to make a sample build in which we use the same setup and calls as in our regular environment but I am able to receive and handle messages without crashing.

Our regular environment consists of plug-ins for an Adobe InDesign CC 2015 and Adobe InCopy CC 2015 setup so it is virtually impossible to have you recreate that. Especially for the Debug target.

We have now planned this to have a lower priority because we can test around it and also because of the low staffing during the summer holidays. When we pick this up again we will contact you again if necessary.

Thanks for all your help so far.