I have a c++ dll which serving some functionality to my main c# application. Here i try to read a file, load it to memory and then return some information such as the Pointer to loaded data and count of memory blocks to c#. The Dll reads file to memory successfully but on the return to the main application, program crashes due to Heap Corruption(Critical error detected c0000374).
The code is quite simple and straightforward and I have done some similar things before with no problem, However i could not figure out what makes the problem here, I tried to allocate memory using "new, malloc and GlobalAlloc" but neither did help. Codes are as follow:
C++ MyDll:
typedef unsigned long U32;
extern "C" __declspec(dllexport) int ReadFile(LPSTR Path, U32** DataPtr, U32* Count)
{
FILE *fp;
U32 *Data;
CString tempStr(Path);
long fSize;
if(!(fp = fopen(tempStr, "rb"))) {
return 0;
}
// Obtain File Size;
fseek(fp, 0, SEEK_END);
fSize = ftell(fp);
rewind(fp);
Data = (U32 *)GlobalAlloc(0, fSize);
if(Data == NULL) {
fclose(fp);
return -1;
}
// Copy file into the buffer.
if(!(*Count = fread(Data, sizeof(U32), fSize / sizeof(U32), fp))) {
fclose(fp);
free(Data);
return -2;
}
*DataPtr = (U32 *)Data;
return 1;
}
C# Application:
[DllImport(@"MyDll.dll", CallingConvention= CallingConvention.Cdecl)]
private static extern int ReadFile([MarshalAs(UnmanagedType.LPStr)]string Path, out IntPtr dataPtr, out uint Count);
private void readDump(string Path)
{
uint count = 0;
IntPtr Data = new IntPtr();
try{
if(ReadFile(Path, out Data, out count) == 1) //The Program crashes just right after this statement
{
//Do Something ...
}
}
catch() {}
}
The program crashes on both debug and release mode. Unless I pause the program in debug mode after loading the file and call some blocks of memory in the "Visual Studio's Immediate window". The size of files to be loaded are around 64MB and we have more than 2GB unused ram on the PC.
UPDATE: I noticed that, some third party programs which they working before, crash with "Exception Code: c0000005", and some other weird things happens in Windows 7 (the Host). so I tested the code in another installation of windows and everything seems to work as they should. So probably it's related be the Windows 7. Now how could I fix the problem? "sfc /scannow" failed to find any issue.
I'm late to the party but here I go.
I received this error code from my own program, which brought me to this post. I was setting an array position out of range, causing the next allocation to crash the program, in Windows 7. I found the error by compiling with the -g flag with gcc from MinGW and then running the program with gdb. Somewhere here you read or write an invalid location and the next allocation picks up on the heap corruption. I solved my problem by bounds checking my iterators, but that doesn't seem to be the problem here.
Main Problems with the C Program:
FILE_SIZE % 4 == 1
then there are 3 bytes which are not part of your allocated data, but are accessed when you look at the final element of the u32 array. Solutions:
That version of software may have been doing some extra work when casting so that it wrote to a location out of range, or C# made some extra allocation calls that would do the same (I am not familiar with how C# compiles and what instruction changes it may impose).
Some code for finding the next multiple of 4:
size_t diff, rfSize = fSize; /* size_t is preferable for array sizes and indexes,
* but matching to fSize's data type will work and
* ensures no truncation occurs. */
/* Only if this is not already a multiple of 4 */
if (diff = fSize % 4)
/* Mod gives the remainder by division by 4, which is also the difference between
* fSize and the next multiple of 4. */
rfSize= fSize + diff;
If all your code is indeed what is shown above, then I don't see the problem. However, when I get this issue, sometimes its because malloc/new/whatever detects heap corruption, often this corruption has already occurred previously in the program, but the crash has been delayed until the next call to new/malloc.
If you read other files, or allocate or free other buffers before the above is executed and crashes, I would look there for problems. Perhaps throw a bunch of asserts anywhere you write to buffers and check the bounds and what you are writing for overruns. Sorry this isn't a concrete answer, I do not have enough rep to leave this advice as a comment.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With