LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

[CVI2015 SP1]Dynamic memory is corrupt error at Windows Server 2012 R2

This program is the Data Server side as a tcp program between PC and Data Server.
OS: Windows Server 2012 R2, LabWindwos 2015 SP1

Attached program is based on the CVI tcp example "MultiClientServer".
The PPT code is a server-side program, pressing the PC (GUI) button performs slide1, and slide2 is performed by the last PostDeferredCallToThread of slide1.
On the first run, the last free function of slide2 is OK, but the second time, it encounters a runtime error called "Dynamic memory is corrupt".
When I had check the data sent by the PC, 
the server's received data and length was correct.

Please tell me your opinions.
0 Kudos
Message 1 of 6
(2,427 Views)

In this loop:

 

while(bytesToWrite>0)
{
    bytesWritten=ServerTCPWrite (clientInfoPtr->handle, &clientInfoPtr->sendbuf[msgSize-bytesToWrite], 
                                 bytesToWrite, 0);
    bytesToWrite-=bytesWritten; 
}

you may actually want to check that ServerTCPWrite is not returning a negative value indicating an error of some sort and if so either skip the advancement of the bytesToWrite value or exit the loop altogether.

 

Since this loop is only reading the buffer it can't really be the cause of the observed error but I'm pretty sure there are other similar problems that could cause a buffer overrun, which is what causes your error message here. I would check the loop that fills in the sendbuf to be transmitted by the deferredSendtoClient() function. It is most likely the culprit. And of course make sure that you really malloc at least clientInfoPtr->sendDataSize bytes for that buffer!

Basically when you run in debug mode and allocate memory through the CVI malloc functions CVI will create a trampoline around those bufferes by allocating slightly larger buffers and fillig the trampoline area with a specific bit pattern. On free it will check those trampoline areas to still be untouched and if they are not, someone somewhere wrote beyond the buffer limits and should be flogged for it. Smiley LOL

 

In general there is more to mention about the code as is. You do not check that sendbuf is not a NULL pointer before dereferncing it to read the msgID but you check it later on to be not NULL before attempting to free it. Either you can guarantee that it is always a valid buffer and then you don't need to check it before freeing it as it can't suddenly disappear while reading it to be send of to the client, or you can not guarantee it and then you should check it first thing before trying to read from it.

 

In the deferredRcvfromPxi() function you use sometimes sizeof (header.dword.head) and sometimes HEADERSIZE, which is not clear to be guaranteed to be the same. In there you treat the first four bytes apparently as an struct containing a 16 bit value that contains the msgID and another 16 bit value that indicates the message size but in your  deferredSendtoClient() function you treat the entire 4 bytes as msgID. While it's not clear they would need to match it is definitely a source of potential confusion for any developer having to look at that code and maintain it.

 

sizeof(unsigned char)*clientInfoPtr->sendthreadId is really just Rube Goldberg as sizeof(unsigned char) will on any computer that CVI is ever going to run on probably always be 1, and if it won't you have other bigger problems to worry about as you will send off the wrong or invalid threadID to the function.

Rolf Kalbermatter
My Blog
Message 2 of 6
(2,410 Views)
Thank you for your advice.
I'll check and let you know the results.

Maybe, Is there a bug in the CVI tool itself?
My OS is windows serrver 2012 R2
0 Kudos
Message 3 of 6
(2,358 Views)

There is always a possibility for a bug in CVI. But from what I have seen in the code you show, the chance that something is wrong in there rather than CVI is definitely a lot higher. Part of developing code is also the debugging. Do that and make sure you don't overwrite the memory buffer beyond its allocated size and then you can come back and suspect bugs in CVI.

Just showing a bit of code and hoping the problem resolves itself by expecting some bug in the LabWindows/CVI libraries is not going to work. The reality works the other way around. You have to provide an example that proofs beyond any reasonable doubt that you can produce a wrong behaviour with 100% correctly written code to claim that it is a bug in LabWindows/CVI.

 

Part of debugging could be for instance explicit checking of the index you attempt to write into the buffer in the copy loop to be always between 0 and n-1 with n being the size of the allocated buffer. If you never hit that condition in the loop and then still get that error you at least know that your writer loop is fine (but still not that some other part of your application is misbehaving by trying to write to an invalid pointer or beyond its own buffer end which could wrap into the trampoline area for your dynamically allocated buffer).

 

Rolf Kalbermatter
My Blog
0 Kudos
Message 4 of 6
(2,353 Views)

HI rolfk

 

Like your a previous advise, At below codes really can try read more than bytesToRead but I think In that case run-time error occurr and really I've already experienced.

 

bytesRead=ServerTCPRead (pxiInfoPtr->handle, &tcpReadbuf[HEADERSIZE+(msgSize-bytesToRead)], bytesToRead, 0);

 

and I think, if ServerTCPRead() or ServerTCPWrite() returned negative error value,
it will already encounter an error beyond array index or out of boundary ... because it refers to an array index that is larger than the size of the buffer.


Can suddenly there be a dynamc memory corruption without these errors(Incorrect array index, Beyond array index or out of boundary..etc)?

 

Please see attacked file(PPT)

 

 

0 Kudos
Message 5 of 6
(2,327 Views)

Well, if ServerTCPRead() (or ServerTCPWrite()) returns an error the return value will be negative and instead of NOT reducing the bytes to read you will actually increase it and resending some of the already send data again, causing the other side to likely overrun their buffer since you read the first four bytes to determine how much data will follow but there will be potentially more. So you really need to make that code more robust.

 

As to memory corruption: Any place inside your process could be the culprit. Yes that includes LabWindows/CVI library routines, especially if you pass wrong parameters to it, but assuming that the error is NOT in your code but rather caused by LabWindows/CVI without stone hard proof in the form of some example code proofing this, is like closing your eyes while driving with 400 on the highway and hoping everything goes right. You are doing the wrong thing but will blame the idiot who didn't anticipate you driving like a madman for any accident! Smiley Very Happy

 

In over 30 years of programming, expecting the libraries I was using to be the bad guy never helped me to find a bug, assuming that the bug was caused by me and investigating it until I could proof beyond any doubt that I was doing everything correct however always got me to crush the bug, and in 99% of the cases it was in my code! So act accordingly! Debug, debug and debug until you know where the problem is. This error is not an indication of a programming bug you can take lightly, memory corruption is a serious problem and one very easily done in C code. C doesn't have automatic buffer overrun protection. The dynamic memory trampoline that LabWindows/CVI is using in debug mode is about as much as you can get, safe from running your entire source code through code analyzers like Valgrind or similar.

 

Such an analyzer would currently be not only moaning but screaming when pointed to the code you show.

Rolf Kalbermatter
My Blog
Message 6 of 6
(2,307 Views)