This tutorial describes how to detect memory leaks in a service.
This tutorial covers the following:
Related tutorials:
Detecting memory leaks in an application that is a child process of a service.
Detecting memory leaks in an IIS ISAPI DLL.
Detecting memory leaks in ASP.Net with IIS.
Detecting memory leaks in ASP.Net with Web Development Server.
Detecting detect memory leaks for a child process.
This tutorial applies to all native services and to mixed-mode services that start the service that uses the native Win32 services API.
If your service is written entirely in .Net or .Net Core, or your service is mixed-mode with the startup code written in .Net or .Net core you can skip the part of this tutorial relating to the NT Service API and go straight to the detecting memory leaks in a service section.
Memory Validator ships with an example service in the examples\service folder in the Memory Validator installation directory.
or
or
The service has already been modified to use the NT Service API. In this tutorial, we’ll describe the modifications you would make to the service to make it work correctly with Memory Validator.
The NT Service API is a simple API that allows you to load the Memory Validator profiling DLL and start the process of collecting detecting memory leaks.
The API also includes some debugging functions to help provide debugging information via log files (the only way to get data out of a service without a connection to the Memory Validator user interface).
The purpose of serviceCallback() is to regularly tell the service control manager that the service is alive. This prevents the service from being killed for being unresponsive if the instrumentation of your service takes too long (where too long is defined by the service control manager).
void serviceCallback(void *userParam) { // just tell the Service Control Manager that we are still busy // in this example userParam is not used static DWORD dwCheckPoint = 1; ssStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; ssStatus.dwServiceSpecificExitCode = 0; ssStatus.dwControlsAccepted = 0; ssStatus.dwCurrentState = dwCurrentState; ssStatus.dwWin32ExitCode = dwWin32ExitCode; ssStatus.dwWaitHint = dwWaitHint; ssStatus.dwCheckPoint = dwCheckPoint++; // Report the status of the service to the service control manager. return SetServiceStatus(sshStatusHandle, &ssStatus); }
svlMVStub_setLogFileName(SZLOGFILENAME); svlMVStub_deleteLogFile();
#ifdef IS6432 // x86 with x64 GUI errCode = svlMVStub_LoadMemoryValidator6432(); #else //#ifdef IS6432 // x86 with x86 GUI // x64 with x64 GUI errCode = svlMVStub_LoadMemoryValidator(); #endif //#ifdef IS6432 if (errCode != SVL_OK) { DWORD lastError; lastError = GetLastError(); svlMVStub_writeToLogFileW(_T("Memory Validator load failed. \r\n")); svlMVStub_writeToLogFileLastError(lastError); svlMVStub_writeToLogFile(errCode); svlMVStub_dumpPathToLogFile(); } else { svlMVStub_writeToLogFileW(_T("Memory Validator load success. \r\n")); }
errCode = svlMVStub_SetServiceCallback(serviceCallback, // the callback NULL); // some user data if (errCode != SVL_OK) { svlMVStub_writeToLogFileW(_T("Setting service callback failed. \r\n")); svlMVStub_writeToLogFile(errCode); }
errCode = svlMVStub_StartMemoryValidator();
if (errCode != SVL_OK)
{
DWORD lastError;
lastError = GetLastError();
svlMVStub_writeToLogFileW(_T("Starting Memory Validator failed. \r\n"));
svlMVStub_writeToLogFileLastError(lastError);
svlMVStub_writeToLogFile(errCode);
}
else
{
svlMVStub_writeToLogFileW(_T("Finished loading Memory Validator\r\n"));
}
Now that the NT Service API has been implemented in your service, we can start collecting memory allocation data from the service.
Select the service executable you are going to monitor. For this example, the application is examples\service\Release_2010_x64\serviceMV_x64.exe.
Choose the appropriate native/mixed-mode/.Net option to specify which types of code you want to detect memory leaks for. Mixed-mode is the default, as this collects memory allocation information for all types of code.
To finish detecting memory leaks, you need to stop your service.
Memory Validator will monitor memory allocations and deallocations the service shutdown procedure and then present you with the memory leak report.
There are a few things to check.
svlMVStub_setLogFileName(SZLOGFILENAME);
You have learned how to add the NT Service API to a native service, how to use Memory Validator to monitor a service, and what to look at to diagnose errors if things don’t work first time.