|
|
|
date: Wed, 16 Apr 2008 01:12:01 -0700,
group: microsoft.public.win32.programmer.wmi
back
WMI server process leak querying performance data
Hi,
We found a memory leak problem in WMI while querying some performance
classes in remote systems with Windows Vista or Windows Server 2008 without
using refreshers, only executing simple queries. This not happens on a
Windows XP remote system.
We made a test program to show the memory use of the WMI remote service.,
the code of that application is incuded below on this post. The application
just connects to a remote system, establishes the security options and do a
simple query, releasing inmediately the answer and not processing it. Then we
release all the components. The code is prepared to loop only the query
section or the full connect-query-release process or both.
If we only query "Select * from Win32_PerfRawData_PerfProc_Process" a
number of times, the remote WMI server processes begin to consume memory
(Commit Size) until a 0x800706ba error (The RPC server is unavailable) is
raised, which stops the test application. A while after, all the WMI server
processes created for the application dissappear. This happens only in
Windows Server 2008, in Vista we were unable to reproduce this bahaviour.
If we try to loop the full process instead of doing a lot of performance
queries in the inner loop, the server process Commit Size grows, and when the
memory reaches some level, the process restarts and no error is raised on the
test application.
When we repeat all those tests with the query "Select * from
Win32_OperatingSystem" then no increase in the Commit Size is shown. This is
also true if we run the same tests targetting a Windows XP system with both
those queries.
Regards,
Tango
To make the code work, change the user, password and remote namespace to the
proper values:
#define _WIN32_DCOM
#include <iostream>
using namespace std;
#include <Wbemidl.h>
# pragma comment(lib, "wbemuuid.lib")
#define NUMBER_OF_REFRESHES 1
#define NUMBER_OF_FULL_LOOPS 1
#define NAME_SPACE L"\\\\Remote_System\\root\\cimv2"
#define DOMAIN L"Domain"
#define USER L"User"
#define FULL_USER L"Domain\\User"
#define PASSWORD L"Password"
#define QUERY_TYPE L"WQL"
#define QUERY L"Select * from Win32_PerfRawData_PerfProc_Process"
//#define QUERY L"Select * from Win32_OperatingSystem"
int __cdecl wmain(int argc, wchar_t* argv[])
{
HRESULT hr = S_OK;
IWbemRefresher *pRefresher = NULL;
IWbemConfigureRefresher *pConfig = NULL;
IWbemHiPerfEnum *pEnum = NULL;
IWbemServices *pNameSpace = NULL;
IWbemLocator *pWbemLocator = NULL;
IUnknown *pUnkServ = NULL;
SEC_WINNT_AUTH_IDENTITY_W *pAuthIdentity = NULL;
IEnumWbemClassObject *pEnumerator = NULL;
BSTR bstrNameSpace = NULL;
BSTR bstrUserName = NULL;
BSTR bstrPassword = NULL;
BSTR userbstr = NULL;
BSTR domainbstr = NULL;
BSTR bstrQueryType = NULL;
BSTR bstrQuery = NULL;
long lID = 0;
long lVirtualBytesHandle = 0;
long lIDProcessHandle = 0;
DWORD dwVirtualBytes = 0;
DWORD dwProcessId = 0;
DWORD dwNumObjects = 0;
DWORD dwNumReturned = 0;
DWORD dwIDProcess = 0;
DWORD i=0;
int x=0;
int y=0;
for(y = 0; y < NUMBER_OF_FULL_LOOPS; y++)
{
hr = S_OK;
pRefresher = NULL;
pConfig = NULL;
pEnum = NULL;
pNameSpace = NULL;
pWbemLocator = NULL;
pUnkServ = NULL;
pAuthIdentity = NULL;
pEnumerator = NULL;
bstrNameSpace = NULL;
bstrUserName = NULL;
bstrPassword = NULL;
userbstr = NULL;
domainbstr = NULL;
bstrQueryType = NULL;
bstrQuery = NULL;
lID = 0;
lVirtualBytesHandle = 0;
lIDProcessHandle = 0;
dwVirtualBytes = 0;
dwProcessId = 0;
dwNumObjects = 0;
dwNumReturned = 0;
dwIDProcess = 0;
i=0;
x=0;
y=0;
if (FAILED (hr = CoInitializeEx(NULL,COINIT_MULTITHREADED)))
{
goto CLEANUP;
}
if (FAILED (hr = CoCreateInstance(
CLSID_WbemLocator,
NULL,
CLSCTX_INPROC_SERVER,
IID_IWbemLocator,
(void**) &pWbemLocator)))
{
goto CLEANUP;
}
// Connect to the desired namespace.
bstrNameSpace = SysAllocString(NAME_SPACE);
if (NULL == bstrNameSpace)
{
hr = E_OUTOFMEMORY;
goto CLEANUP;
}
userbstr = SysAllocString(USER);
if (NULL == userbstr)
{
hr = E_OUTOFMEMORY;
goto CLEANUP;
}
domainbstr = SysAllocString(DOMAIN);
if (NULL == domainbstr)
{
hr = E_OUTOFMEMORY;
goto CLEANUP;
}
bstrUserName = SysAllocString(FULL_USER);
if (NULL == bstrUserName)
{
hr = E_OUTOFMEMORY;
goto CLEANUP;
}
bstrPassword = SysAllocString(PASSWORD);
if (NULL == bstrPassword)
{
hr = E_OUTOFMEMORY;
goto CLEANUP;
}
if (FAILED (hr = pWbemLocator->ConnectServer(
bstrNameSpace,
bstrUserName, // User name
bstrPassword, // Password
NULL, // Locale
0L, // Security flags
NULL, // Authority
NULL, // Wbem context
&pNameSpace)))
{
goto CLEANUP;
}
pWbemLocator->Release();
pWbemLocator=NULL;
SysFreeString(bstrNameSpace);
bstrNameSpace = NULL;
SysFreeString(bstrUserName);
bstrUserName = NULL;
pAuthIdentity = new SEC_WINNT_AUTH_IDENTITY_W;
SecureZeroMemory(pAuthIdentity, sizeof(*pAuthIdentity));
pAuthIdentity->User = new WCHAR[100];
wcscpy (pAuthIdentity->User , userbstr);
pAuthIdentity->UserLength = wcslen(pAuthIdentity->User);
SysFreeString(userbstr);
userbstr = NULL;
pAuthIdentity->Domain = new WCHAR[100];
wcscpy(pAuthIdentity->Domain, domainbstr);
pAuthIdentity->DomainLength = wcslen(pAuthIdentity->Domain);
SysFreeString(domainbstr);
domainbstr = NULL;
pAuthIdentity->Password = new WCHAR[wcslen(bstrPassword)+1];;
wcscpy(pAuthIdentity->Password, bstrPassword);
pAuthIdentity->PasswordLength = wcslen(pAuthIdentity->Password);
SysFreeString(bstrPassword);
bstrPassword = NULL;
pAuthIdentity->Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
if (FAILED (hr = CoSetProxyBlanket(pNameSpace,
RPC_C_AUTHN_WINNT,
RPC_C_AUTHZ_NONE,
NULL,
RPC_C_AUTHN_LEVEL_PKT,
RPC_C_IMP_LEVEL_IMPERSONATE,
pAuthIdentity,
EOAC_NONE)))
{
goto CLEANUP;
}
if (FAILED (hr = pNameSpace->QueryInterface(IID_IUnknown, (void**)
&pUnkServ)))
{
goto CLEANUP;
}
if (FAILED (hr = CoSetProxyBlanket(pUnkServ,
RPC_C_AUTHN_WINNT,
RPC_C_AUTHZ_NONE,
NULL,
RPC_C_AUTHN_LEVEL_PKT,
RPC_C_IMP_LEVEL_IMPERSONATE,
pAuthIdentity,
EOAC_NONE)))
{
goto CLEANUP;
}
bstrQueryType = SysAllocString(QUERY_TYPE);
bstrQuery = SysAllocString(QUERY);
for(x = 0; x < NUMBER_OF_REFRESHES; x++)
{
if (FAILED (hr = pNameSpace->ExecQuery(
bstrQueryType,
bstrQuery,
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
NULL,
&pEnumerator)))
{
goto CLEANUP;
}
if (NULL != pEnumerator)
{
pEnumerator->Release();
pEnumerator = NULL;
}
}
// exit loop here
CLEANUP:
if (NULL != bstrNameSpace)
{
SysFreeString(bstrNameSpace);
}
if (NULL != bstrUserName)
{
SysFreeString(bstrUserName);
}
if (NULL != userbstr)
{
SysFreeString(userbstr);
}
if (NULL != domainbstr)
{
SysFreeString(domainbstr);
}
if (NULL != bstrPassword)
{
SysFreeString(bstrPassword);
}
if (NULL != bstrQueryType)
{
SysFreeString(bstrQueryType);
}
if (NULL != bstrQuery)
{
SysFreeString(bstrQuery);
}
if (NULL != pEnumerator)
{
pEnumerator->Release();
}
if (NULL != pWbemLocator)
{
pWbemLocator->Release();
}
if (NULL != pNameSpace)
{
pNameSpace->Release();
}
if (NULL != pUnkServ)
{
pUnkServ->Release();
}
if (NULL != pAuthIdentity)
{
if (NULL != pAuthIdentity->User)
delete [] pAuthIdentity->User;
pAuthIdentity->User = NULL;
if (NULL != pAuthIdentity->Domain)
delete [] pAuthIdentity->Domain;
pAuthIdentity->Domain = NULL;
if (NULL != pAuthIdentity->Password)
delete [] pAuthIdentity->Password;
pAuthIdentity->Password = NULL;
}
if (NULL != pEnum)
{
pEnum->Release();
}
if (NULL != pConfig)
{
pConfig->Release();
}
if (NULL != pRefresher)
{
pRefresher->Release();
}
CoUninitialize();
if (FAILED (hr))
{
wprintf (L"Error status=%08x\n",hr);
}
}
wprintf (L"End");
Sleep(600000);
return 1;
}
date: Wed, 16 Apr 2008 01:12:01 -0700
author: Tango am
|
|