22 July, 2025

Using EurekaLog with FastMM's full debug mode

Were were contacted by a customer who claimed adding EurekaLog to his application prevented FastMM from doing its job. Specifically, FastMM could detect a problem like this:
SomeObj.Free;
SomeObj.SomeField := 1; // here: writing into released memory
but only in an application without EurekaLog. Once EurekaLog is added to an application, the FastMM no longer detects the "bad" code.

First of all: these kinds of checks highly depend on order in which memory operations are performed. FastMM does not detect writes into released memory as soon as the write operation completes. Instead, FastMM perform memory scanning check when your app request memory to be allocated in the same place - which can happen a lot later; or it could never happen at all.

For example:
SomeObj.Free;
SomeObj.SomeField := 1; // this will not be detected

TSomeObj.Create; // here: FastMM will allocate the object over the old memory block 
                 // and it will detect the old memory block was changed

Additionally, you can tell FastMM to force-scan all released memory via the FastMM_ScanDebugBlocksForCorruption function at any time.

So one might think adding EurekaLog to an application changed the order of memory operations, so app's behaviour changed. However, that was not the case.

EurekaLog does not have its own memory manager. EurekaLog uses memory manager of your app - whatever it is set to. EurekaLog just adds some extra features to perform few memory checks. It is all done as layer on top of your existing memory manager. So, if you add FastMM to your project and then enable EurekaLog with memory checks - your app will use FastMM to allocate memory, while EurekaLog will use that memory to store extra data for memory checks.

The customer used FastMM 5. Unlike FastMM 4 (which enables full debug mode via conditional symbols), FastMM 5 can enable full debug mode by calling the FastMM_EnterDebugMode function. This function is so convenient, most people use it everytime, without realizing what it actually does.

The way full debug mode in FastMM works is that it is actually two different memory managers: the "release" one (FastMM_GetMem) and full debug mode one (FastMM_DebugGetMem). This was more obvious in FastMM 4, as enabling full debug mode required changing conditional symbols and a standalone DLL. So the FastMM_EnterDebugMode function simply switches the FastMM_GetMem to the FastMM_DebugGetMem. What people don't realize is that it is only possible if your app still uses FastMM_GetMem. Indeed: that way full debug mode will know how to release memory allocated by the FastMM_GetMem.

However, if memory manager was already set to something else (like EurekaLog's memory filter), the full debug mode would have no idea how to work with EurekaLog headers. Thus it won't be able to properly free memory allocated via EurekaLog. That is why the FastMM_EnterDebugMode function will no nothing when called in an application with EurekaLog (well, assuming it is called after EurekaLog's initialization). You can verify this:
if FastMM_EnterDebugMode then
  OutputDebugMode('FastMM5: FULL DEBUG MODE ENABLED');
You will see this output in an app without EurekaLog, but not in app with EurekaLog.

That was exactly what customer did: he called the FastMM_EnterDebugMode function as first action in his project file (.dpr), but it is already too late: EurekaLog (as well as RTL and VCL) is already initialized at this point, so EurekaLog's memory filter is already set, therefore the FastMM_EnterDebugMode function will do nothing.

That was the reason: FastMM 5 did not detect anything, because FastMM's full debug mode was not enabled in the first place.

Is it possible to use FastMM 5 in full debug mode with EurekaLog?

Yes! All you need to do is to enable FastMM's full debug mode before EurekaLog sets its memory manager. In other words, the FastMM_EnterDebugMode function should be called before EMemLeaks unit initializes. Order of initialization matters. You can do this in at least two different ways:
  1. If you open the FastMM5.pas file, you would see documentation for FastMM. It mentions this among other things:
    The following conditional defines are supported:
    - FastMM_FullDebugMode (or FullDebugMode) - If defined then FastMM_EnterDebugMode will be called on startup so that the memory manager starts in debug mode. If FastMM_FullDebugMode is defined and FastMM_DebugLibraryDynamicLoading (or LoadDebugDLLDynamically) is not defined then FastMM_DebugLibraryStaticDependency is implied.

    - FastMM_FullDebugModeWhenDLLAvailable (or FullDebugModeWhenDLLAvailable) - If defined an attempt will be made to load the debug support library during startup. If successful then FastMM_EnterDebugMode will be called so that the memory manager starts up in debug mode.
    which means you can add the FastMM_FullDebugMode (or FastMM_FullDebugModeWhenDLLAvailable) conditional symbol to your project's options. You probably want to add it into your "Debug" build configuration only. Now, build your project, and it will have FastMM 5 in full debug mode for the "Debug" build configuration, but production version of FastMM 5 for the "Release" build configuration.

    That way the FastMM_EnterDebugMode function will be called when the FastMM5 unit is initialized - i.e. before the EMemLeaks unit is initialized.
     
  2. Another way would be creating a FastMM5_FDM.pas unit like this:
    unit FastMM5_FDM;
    
    interface
    
    implementation
    
    uses
      FastMM5;
    
    initialization
      FastMM_EnterDebugMode;
    
    end.
    Place this unit as your first unit:
    uses
      FastMM5_FDM,
      {$IFDEF EurekaLog}
      EMemLeaks,
      EResLeaks,
      // ...

    That way the FastMM_EnterDebugMode function will be called when the FastMM5_FDM unit is initialized - i.e. before the EMemLeaks unit is initialized.
All mentioned methods will call the FastMM_EnterDebugMode function first, and then initialize EurekaLog's memory filter:
  • The FastMM_FullDebugMode will enable full debug mode at design-time;
  • The FastMM_FullDebugModeWhenDLLAvailable will enable full debug mode depending if the debug support library is present;
  • The FastMM5_FDM unit will enable full debug mode at the run-time.