Memory leak with SetSystemTime/SetLocalTime

Hello, we encountered low program memory error after running a series of procedures on our application. We found out that there are multiple application repllog.exe and it seems that a new instance is being spawned until there is no memory left and the system crashes.

After some research we came upon this post in one of the forums https://forum.fs-net.de/index.php?thread/3924-memory-leak-in-windows-compact-7/. This helped us isolate the problem to be SetLocalTime/SetSystemTime. It seems that if the Explorer is not running, setting the time spawns a new instance of repllog.exe. The aforementioned forum post gives several work-arounds:

  • kill “repllog” from time to time…
  • Remove Active Syc…
  • Call “ShellRegisterCallbacks()”…

But we are wondering if any of you have the same experience and could give us some advice how to handle this properly.

Dear @dennisL,

Thank you for contacting support with details. We don’t know any other solution apart from you mentioned. We would like to share a tool to repllog time sync event, please download the control panel applet and put it in the device windows folder and run the tool. Select the “repllog.exe Time modified” event and click File → Delete it.
But this is not persistent after reboot.

Hello, thank you for your response and for the tool. However, I have to ask whether this tool merely kills instances of repllog.exe or does it prevent newer instances of repllog.exe to be spawned for each Time modification?

The point is I could not properly test it because on our system we have suppressed Explorer during start-up which is actually the cause why we are encountering the multiple repllog.exe instance problem. In order for me to be able to test the control panel applet, I need to launch Explorer.exe to be able to start the applet (PHMNtfy).

However, the very act of launching Explorer already clears all running instances of repllog.exe so I could not verify how the control panel applet works in relation to controlling the repllog.exe processes.

Dear @dennisL,

It actually deletes the event on the database, so it does prevent newer instances of repllog.exe to be spawned for each Time modification.

Hello again. That would actually be helpful for our situation. Is there a way to do this programmatically?

For the moment, we have created a small shell replacement with just the minimum functionality to allow repllog.exe to terminate itself normally whenever the system time is set. However, if it is possible to somehow include directly in our software what the PHMNtfy control panel applet does, that would be very interesting and worth considering.

Dear @DennisL,

Thank you for your reply. By using below code you can delete the repllog.exe event and you need to pass L"repllog.exe" to the function.

#include "notify.h"
// -------------------------------------------------------------------
/// @internal
/// Remove any notification whose registered name contains <exePath>.\n
/// Similar to CeRunAppAtEvent(exePath, NOTIFICATION_EVENT_NONE));
/// @param[in]    exePath        (partial) application name or event name
/// @retval        TRUE        successful
/// @retval        FALSE        Error occured
static BOOL ClearNotification(TCHAR *exePath)
{
    CE_NOTIFICATION_INFO_HEADER  *pBuffer;
    CE_NOTIFICATION_TRIGGER         *pTrigger;
    DWORD                          dwHowMany;
    HANDLE                         *hNotifications;
    DWORD                          pcBytesNeeded;
    BOOL                          Success = TRUE;

    // evaluate number of existing notifications
    if (!CeGetUserNotificationHandles(NULL,0,&dwHowMany))
        return FALSE;

   if(dwHowMany==0)
   { // no notifications available -> nothing to clear -> return true!
       return TRUE;
   }

    // Get all existing notification handles
    hNotifications = LocalAlloc(0, 4*dwHowMany);
    Success = CeGetUserNotificationHandles(hNotifications, dwHowMany, &dwHowMany);
    if (!Success) goto abort;

    // Process each notification handle
    while (dwHowMany--)
    {    
        // evaluate buffer size
        CeGetUserNotification(hNotifications[dwHowMany], 0, &pcBytesNeeded, NULL);

        // read notification information
        pBuffer = LocalAlloc(0, pcBytesNeeded);
        if (CeGetUserNotification(hNotifications[dwHowMany], pcBytesNeeded, &pcBytesNeeded, (LPBYTE)pBuffer))
        {
            pTrigger = pBuffer->pcent;
            if (NULL != _tcsstr(pTrigger->lpszApplication, exePath))        // if this is our notification...
                Success = CeClearUserNotification(hNotifications[dwHowMany]);    // ... clear it
        }
        LocalFree(pBuffer);
    }

abort:
    LocalFree(hNotifications);
    return Success;
}

Please feel free to contact us if you need any support on this.

Thank you very much. This solved our problem.