3

I'm hunting an elusive memory problem in a Delphi 5 program, where memory gets randomly overwritten at the customer site. After trying a lot of things with no result so far I now want to use the FastMM4 output from the LogAllocatedBlocksToFile() to find out which objects are allocated immediately before the overwritten area. The program uses a timer to write allocated block information to a new file every 30 minutes. Unfortunately my test run of the program (DEBUG build) crashed after about 23 hours with an EOutOfMemory exception, using allocated memory of 1.83 GB according to MadExcept.

From SysInternals Process Explorer it does look like each call of LogAllocatedBlocksToFile() allocates but does not free memory:

Process Explorer screen shot of a 100 minutes program run

The red spikes in the CPU Usage graph are the LogAllocatedBlocksToFile() calls. I have added calls to LogMemoryManagerStateToFile() immediately before and after, and the data for the last spike (increse of the private bytes from about 183 MB to about 218 MB) looks like this:

55054K Allocated
47911K Overhead
53% Efficiency

and this:

55055K Allocated
47910K Overhead
53% Efficiency

so FastMM4 seems not to be aware of the additional memory the program consumes according to Process Explorer.

I'm using version 4.991 of FastMM4, downloaded today from SourceForge. The test program runs in DEBUG mode, with the following defines set:

FullDebugMode

UseCustomFixedSizeMoveRoutines
UseCustomVariableSizeMoveRoutines
NoDebugInfo
ASMVersion
DetectMMOperationsAfterUninstall
RawStackTraces
LogErrorsToFile
LogMemoryLeakDetailToFile
AlwaysAllocateTopDown
SuppressFreeMemErrorsInsideException
EnableMemoryLeakReporting
HideExpectedLeaksRegisteredByPointer
RequireDebuggerPresenceForLeakReporting
EnableMMX
ForceMMX EnableBackwardCompatibleMMSharing
UseOutputDebugString

Questions:

Is there any known problem with those functions? Am I not using them properly, are they not intended to be called multiple times in one debugging session? Is there a way to get that memory released again?

Community
  • 1
  • 1
mghie
  • 32,028
  • 6
  • 87
  • 129
  • 2
    I can't see anything in the source that would cause this sort of problem. Can you also put a list of the defines that you have set? – Graymatter Mar 17 '14 at 18:55
  • @Graymatter: will do as soon as I'm back at the office in front of the test system which will be on Wednesday - sorry. – mghie Mar 17 '14 at 19:47
  • If memory gets randomly overwritten, perhaps you have better luck using [gFlags](http://msdn.microsoft.com/en-us/library/windows/hardware/ff549557(v=vs.85).aspx)?! You didn't specify if the memory overwrites result in exceptions. If they don't, gFlags is not an option I'm afraid. If they do, it's worth a shot. I'm curious to how you know memory got overwritten in the first place? – Lieven Keersmaekers Mar 18 '14 at 10:43
  • @Graymatter: I have added the information to my question. – mghie Mar 19 '14 at 12:05
  • @LievenKeersmaekers: Memory overwrites are easy to notice, they often modify strings that are either visible in the UI or are written to data files. If string data gets overwritten it's relatively benign, but when the ref count or length of the string are modified sooner or later there will be exceptions in the program. I haven't been able to pinpoint the source of those overwrites yet. The string data should be immutable, but I couldn't make hardware breakpoints on writes to those memory locations work. – mghie Mar 19 '14 at 12:23
  • Just an idea: LogAllocatedBlocksToFile() requires FullDebugMode, but from sources: a) _Except in full debug mode where medium pools are never freed._ b) _Small block pools are never freed in full debug mode._ Perhaps a growing memory could be related to this. – pf1957 Mar 19 '14 at 19:11

1 Answers1

7

Short version:

I have tracked this down to be a version mismatch of the support library FastMM_FullDebugMode.dll.

An older version of the library works with the newer version compiled into the executable. There seems to be no check that versions do match. However, modules don't really work together at run-time.

Long version:

The project originally uses the older version 4.97 of FastMM4, which I have checked in here together with the support library (file version 1.44.0.4, product version 1.42).

While trying to find the bug in the program I have upgraded FastMM4 to version 4.991. I also remember to have copied the new support library (file version 1.61.0.6, product version 1.60) to the build directory. However, some time later I must have deleted it from the directory, or I copied it into the wrong directory to begin with, because two hours ago I checked the modules loaded by the application and found that the app had picked up the old version of the support library from another directory, as it was not in the build directory.

Since copying it there and restarting the app the problem seems to be gone. Memory usage doesn't increase when LogAllocatedBlocksToFile() is called.

Maybe this helps someone, so I answer this instead of deleting the question.

On with debugging...

mghie
  • 32,028
  • 6
  • 87
  • 129