I'm facing a strange issue with our code and FastMM, intergrated into C++ Builder 2007.
It appears that at certain conditions FastMM's SysGetMem returns pointer to element of MediumBlockBins array instead of actual allocated memory.
I suspect a some memory corruption here, but still puzzled by very "proper" and "correct" values while entire SysGetMem work.
You can find details in this message: http://news.eurekalog.com/showthread.php?p=8468#post8468
I really appreciate any ideas on how to detect what's going on here.
Pierre le Riche
I suspect you may have a buffer overrun bug in your application. Does "FullDebugMode" pick up any problems?
Unfortunately, any changes in application settings (i.e. using stand-alone FastMM either in normal or full-debug mode, toggling Dynamic RTL, etc) will hide the problem entirely.
And no, full debug (even with scan after any operation) will not reveal anything.
I afraid that these changes just hide the problem, not solve it :(
One more observation: One of the posts in that threads mentions the possibility that you're using different memory managers to operate on the same block (e.g. freeing a block that was allocated with a different memory manager instance). That is a definite no-no, and could cause this kind of corruption. If you want to operate on the same memory blocks across DLLs, etc. you *must* share the same memory manager.
The target application is just empty VCL application with 1 empty DLL.
The problem arise, when both app and DLL are compiled with EurekaLog. But this happens only with certain settings.
With Dynamic RTL and packages OFF there are (indeed) 2 MM operating in address space: one for DLL and another for exe.
Thanks for the idea. Do you have suggestion how to best verify this?
Apparently, "free" block in MediumBlockBins has both pointers point on itself. This is exactly the situation in the thread: SysGetMem picks "free" block for some reason.
Pierre le Riche
I've added a new FullDebugMode feature: Whenever you free or reallocate a block it now checks that the block was actually allocated by the same FastMM instance.
I've created a Subversion repository and uploaded the latest source. You can access it here:
Perhaps this will help in narrowing down the problem.
Thanks, I'll definitely try this.
P.S. I just thought that similar feature was already there in FastMM. I thought that because old Delphi's MM raise either AV or EInvalidPointer, if you try to mess with 2 MM's. I didn't think that FastMM may silently "eats" somebody else's mem-blocks. Thanks for the hint.
BTW, BDS 2007 cries about unknown function _TEXT in FastMM4BCB.cpp. I just removed _TEXT(), leaving only "string", and all runs fine after that.
Ok, I've managed to get an error message about block header corruption, but no message about interfere with other MM. I'll try to dig deeper.
FullDebugModeScanMemoryPoolBeforeEveryOperation := True;
P := BadOperation; // <- GetMem call from BadOperation + operation on it.
ScanMemoryPoolForCorruptions; // <- No error here
FreeMem(P); // <- "Block header corrupted here"
Why ScanMemoryPoolForCorruptions doesn't trigger any error? I thought that it scan entire memory pool and detect any error? Yet, it silently passes and error detected only at FreeMem. Is it possible, that ScanMemoryPoolForCorruptions performs only partial checks?
Pierre le Riche
ScanMemoryPoolForCorruptions should pick up the error. Do you have sample code that shows the behaviour you describe? If you could email me a small test case that would be fantastic.
It is in DebugFreeMem. First it do "if FullDebugModeScanMemoryPoolBeforeEveryOperation then ScanMemoryPoolForCorruptions;", which found nothing. Then it do "if CheckBlockBeforeFreeOrRealloc(LActualBlock, boFreeMem) then", which found a error, while calculating checksum of header, and raises a error.
If you want specific demo - I work with files, provided in this post: http://news.eurekalog.com/showpost.php?p=8315&postcount=4
You'll need a EurekaLog to compile this (I think you can use trial, available at http://www.eurekalog.com/downloads.php ).
BTW, after enabling FastMM for exe, I can no longer get the original situation. Now code advances further and raises a error few MM's operations later.
I can't reproduce this - if I do what you say I get the error on the ScanMemoryPoolForCorruptions call as expected. I reviewed the code as well and I don't see anything wrong.
Hmmm... I don't know then.
I suspect, that it has something to do with this memory corruption.
Is it possible, that due to some bug, this block was somehow excluded from global list of blocks, that is why Scan function do not find anything? But when you call free this block, then DebugFreeMem additionally checks explictly this block? This looks like truly enough for me :)
BTW, I think that I've finally found source of this nasty bug. I just need a little more time to investigate it (unfortunately, I'm not much in C++ Builder), but it looks like it has nothing to do with FastMM or EurekaLog - just bad project settings or something.
Great thanks for that last commit of FastMM - it is this version, which helped me to find the reason :)
Have you considered that it may be a different thread that is corrupting the memory?
The demo application is single-threaded.
There is no other thread in question here.