Simple provider crushing

A

Andrew

Hi,

I implemented a simple WMI Provider in C#.
It is a service which expose 10 instances of a simple WMI Class.
The WMI class pnly expose 4 public properties (Value,Min,Max,StdValue) which
only
return some constant data.

First, I was using MOM 2005 (Windows 2003) to interogate the instances
values.
The problem is that after a time (like 1 or 2 days max) I find the service
crashed. The
interogation is done each 15 seconds.

Then, I wrote a simple reader in C++ which read the instances values (the
reader and service provider are on the same machine with Windows XP). The
behaviour is the
same: the service is crushing after a while.

I do know about some WMI memory leaks but it does not seem this case.
The problems which other users seem to have is when they actually query a
provider values.

It seems like there are some problems with creating a simple provider too.

Again, the test provider is very simple. Here;s the code:

// excerpt from TestWMIService.cs
public class Service1 : System.ServiceProcess.ServiceBase
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
private WMIParameter param1, param2, param3, param4, param5, param6,
param7, param8, param9, param10;

public Service1()
{
// This call is required by the Windows.Forms Component Designer.
InitializeComponent();

param1 = new WMIParameter("inst1");
Instrumentation.Publish(param1);

param2 = new WMIParameter("inst2");
Instrumentation.Publish(param2);

param3 = new WMIParameter("inst3");
Instrumentation.Publish(param3);

param4 = new WMIParameter("inst4");
Instrumentation.Publish(param4);

param5 = new WMIParameter("inst5");
Instrumentation.Publish(param5);

param6 = new WMIParameter("inst6");
Instrumentation.Publish(param6);

param7 = new WMIParameter("inst7");
Instrumentation.Publish(param7);

param8 = new WMIParameter("inst8");
Instrumentation.Publish(param8);

param9 = new WMIParameter("inst9");
Instrumentation.Publish(param9);

param10 = new WMIParameter("inst10");
Instrumentation.Publish(param10);
}

.....

// WMIParameter.cs
using System;
using System.Management.Instrumentation;

namespace TestWMIService
{
[InstrumentationClass(InstrumentationType.Instance)]
public class WMIParameter
{
public WMIParameter(string instName)
{
instanceName = instName;
}

public string InstanceName
{
get
{
return instanceName;
}
}

public double StdDev
{
get
{
return 0.12345;
}
}

public double Min
{
get
{
return -123.45;
}
}

public double Max
{
get
{
return 123.45;
}
}

public double Value
{
get
{
return 123.45;
}
}

private string instanceName;
}
}


The system i tested:
..NET Framework 1.1 with SP1.
Windows XP SP2
Windows 2003 SP1.

I try to use adplus in -crash mode and I got a memory dump with 0x80000003
code. Seems like a heap access violation !?

Any ideas ?
Will replacing the C# provider with a C++ provider solve the problem ?

Thank you.
 
W

Willy Denoyette [MVP]

| Hi,
|
| I implemented a simple WMI Provider in C#.
| It is a service which expose 10 instances of a simple WMI Class.
| The WMI class pnly expose 4 public properties (Value,Min,Max,StdValue)
which
| only
| return some constant data.
|
| First, I was using MOM 2005 (Windows 2003) to interogate the instances
| values.
| The problem is that after a time (like 1 or 2 days max) I find the service
| crashed. The
| interogation is done each 15 seconds.
|
| Then, I wrote a simple reader in C++ which read the instances values (the
| reader and service provider are on the same machine with Windows XP). The
| behaviour is the
| same: the service is crushing after a while.
|
| I do know about some WMI memory leaks but it does not seem this case.
| The problems which other users seem to have is when they actually query a
| provider values.
|
| It seems like there are some problems with creating a simple provider too.
|
| Again, the test provider is very simple. Here;s the code:
|
| // excerpt from TestWMIService.cs
| public class Service1 : System.ServiceProcess.ServiceBase
| {
| /// <summary>
| /// Required designer variable.
| /// </summary>
| private System.ComponentModel.Container components = null;
| private WMIParameter param1, param2, param3, param4, param5, param6,
| param7, param8, param9, param10;
|
| public Service1()
| {
| // This call is required by the Windows.Forms Component Designer.
| InitializeComponent();
|
| param1 = new WMIParameter("inst1");
| Instrumentation.Publish(param1);
|
| param2 = new WMIParameter("inst2");
| Instrumentation.Publish(param2);
|
| param3 = new WMIParameter("inst3");
| Instrumentation.Publish(param3);
|
| param4 = new WMIParameter("inst4");
| Instrumentation.Publish(param4);
|
| param5 = new WMIParameter("inst5");
| Instrumentation.Publish(param5);
|
| param6 = new WMIParameter("inst6");
| Instrumentation.Publish(param6);
|
| param7 = new WMIParameter("inst7");
| Instrumentation.Publish(param7);
|
| param8 = new WMIParameter("inst8");
| Instrumentation.Publish(param8);
|
| param9 = new WMIParameter("inst9");
| Instrumentation.Publish(param9);
|
| param10 = new WMIParameter("inst10");
| Instrumentation.Publish(param10);
| }
|
| ....
|
| // WMIParameter.cs
| using System;
| using System.Management.Instrumentation;
|
| namespace TestWMIService
| {
| [InstrumentationClass(InstrumentationType.Instance)]
| public class WMIParameter
| {
| public WMIParameter(string instName)
| {
| instanceName = instName;
| }
|
| public string InstanceName
| {
| get
| {
| return instanceName;
| }
| }
|
| public double StdDev
| {
| get
| {
| return 0.12345;
| }
| }
|
| public double Min
| {
| get
| {
| return -123.45;
| }
| }
|
| public double Max
| {
| get
| {
| return 123.45;
| }
| }
|
| public double Value
| {
| get
| {
| return 123.45;
| }
| }
|
| private string instanceName;
| }
| }
|
|
| The system i tested:
| .NET Framework 1.1 with SP1.
| Windows XP SP2
| Windows 2003 SP1.
|
| I try to use adplus in -crash mode and I got a memory dump with 0x80000003
| code. Seems like a heap access violation !?
|
| Any ideas ?
| Will replacing the C# provider with a C++ provider solve the problem ?
|
| Thank you.


Implement your provider as a console application to test with (your service
is not a "service" by the way), and let the consumer get the instances in a
loop and watch your providers memory consumption. The memory consumption
should not change , as all you do is publish 10 instances and keep them
published.

What Framework version are you running?

Willy.
 
A

Andrew

The memory consumption does change. It grows alot.
Today for example, I have been running this test service (WMI provider) from
~ 6 hours and now task manager says ~400M for TestWMIService.exe
I am reading the provider values from the C++ test application. As I said in
my post, the service is crashing also when reading from MOM (my target is to
read the provider values from MOM anyway).

I suspect that eventually the service crashes beacuse it will reach the 2GB
limit or close (maybe it will not even get there). (Ive just put performance
monitor to log to a file the system 'Working Set' counter values for the
'TestWMIService.exe' process)

Framework version: .NET Framework v1.1.4322

I don't understand how should making my service a console application helps.
My goal is to implement the provider into a service.
What do you mean by "(your service is not a "service" by the way)" ?
public class Service1 : System.ServiceProcess.ServiceBase

If you want, I can provide the code for TestWMIService and C++ consumer (C++
consumer is taken from MSDN).

Thanks.
 
W

Willy Denoyette [MVP]

| The memory consumption does change. It grows alot.
| Today for example, I have been running this test service (WMI provider)
from
| ~ 6 hours and now task manager says ~400M for TestWMIService.exe

Hard to tell without you posting more code, in the piece you posted, you
simply expose 10 instances of a class, this is not the reason for the
increasing memory consumption, so there must be something else you do in
your service.




| I am reading the provider values from the C++ test application. As I said
in
| my post, the service is crashing also when reading from MOM (my target is
to
| read the provider values from MOM anyway).
|
| I suspect that eventually the service crashes beacuse it will reach the
2GB
| limit or close (maybe it will not even get there). (Ive just put
performance
| monitor to log to a file the system 'Working Set' counter values for the
| 'TestWMIService.exe' process)
|
| Framework version: .NET Framework v1.1.4322
|
| I don't understand how should making my service a console application
helps.

It's easier to debug a console application than a service.

| My goal is to implement the provider into a service.
| What do you mean by "(your service is not a "service" by the way)" ?
| public class Service1 : System.ServiceProcess.ServiceBase
|

Well, you should not do anything else than initializing your class
invariants in the Service1 constructor, you should publish the WMI classes
from your service thread only, the service thread should be created and
started from your OnStart method.


Willy.
 
A

Andrew

The service is running from ~20 hours.
Looking at the logs generated by the 'Working Set' counter i see that the
Mem Usage got till 700M and then dropped to 350M.
At this time, its back to ~700M.

Is this behaviour normal ? I will let the application run and see how long
will last this time.
Willy, can you please look at the source code ?

thank you.
 
W

Willy Denoyette [MVP]

| No, it's the only thing I'm doing.
| Again, I simply expose 10 instances of a wmi class which returns constant
| data (no computation).
|
| I attached 2 zip files containing source codes. The service code has a
setup
| project added to it so you can easily install the service.
| After you installed the service, you need to compile and run the C++
| consumer application.
|
| The Memory Usage in TaskManager becomes more obvious after few mins of
| running the reader.
|
|
|

Don't know how it runs on V1.1 of the framework, but this runs without
leaking on V2.

Didn't use the C++ 'reader', here's the 'reader' I'm using to test.

using System;
using System.Management;
class Program {
public static void Main() {
Run();
}
static void Run()
{
ManagementNamedValueCollection ctx = new
ManagementNamedValueCollection();
using(ManagementClass c = new ManagementClass("\\\\.\\root\\TestWmi",
"WMIParameter",
new ObjectGetOptions(ctx, new TimeSpan(0,0,0,5),true)))
{
for(int i = 0; i < 100000; i++)
{
ManagementObjectCollection moc = c.GetInstances();
foreach(ManagementObject mo in moc){
Console.WriteLine("{0} - {1} ",mo["InstanceId"],
mo["ProcessId"]);
Console.WriteLine("{0} - {1} ",mo["InstanceName"], mo["Max"]);
}
}
}
}
}

Willy.
 
A

Andrew

I will use your reader code and let it run for a period of time. I will get
back with results.
The problems appear after at least 1 day.

What do you think about the memory usage ?
 
W

Willy Denoyette [MVP]

| The service is running from ~20 hours.
| Looking at the logs generated by the 'Working Set' counter i see that the
| Mem Usage got till 700M and then dropped to 350M.
| At this time, its back to ~700M.
|
| Is this behaviour normal ? I will let the application run and see how long
| will last this time.
| Willy, can you please look at the source code ?
|
| thank you.
|
|

Do you mean the WS counter for the provider (the service) process only??
This isn't normal, the service should never consume more than 15-20MB.
When I run this using V2 of the framework, the service WS starts at 10.236 K
(no reader running), and goes up to and fluctuates arround 13 M for 100000
queries (~10000 seconds), using the reader I posted in another reply.

Willy.
 
A

Andrew

Do you mean the WS counter for the provider (the service) process only??
This isn't normal, the service should never consume more than 15-20MB.
When I run this using V2 of the framework, the service WS starts at 10.236
K
(no reader running), and goes up to and fluctuates arround 13 M for 100000
queries (~10000 seconds), using the reader I posted in another reply.

Willy.


Yes, I am talking about the Memory Usage showed by TaskManager under Windows
XP SP2 for the TestWMIService.exe
process while the C++ reader is running.
Like I said, I will test with your C# reader code although I got the same
behaviour with a similar C# reader before (thats why i switched to a C++
reader).
I will get back today with more results.
I will test it also on Framework 2.0.

Thanks
 
A

Andrew

Hi,

Im currently testing your consumer code.
I am testing it on 2 machines with .NET Framework v1.1.
On the machine which had memory usage problems with my consumer, your
consumer doesnt seem to do that.
(but again, the problems i had were not just memory usage; I got also
unexpected crashing with unhandled exceptions like access violations)

But, I see that there is a difference.
Your code gets all the instances at once without doing a WQL query for
specific instances.
All the consumers which I was using (MOM, a C# consumer and the C++ consumer
I gave you; i tried with each) use a WQL query (my goal is to monitor from
MOM; all i want is a WMI Provider which feeds the MOM agent the data but it
seems that even a simple provider has a short lifetime)

Here's how I get the consumers:

in C++ (its in the .zip I gave you; again, I took this from a MSDN example):
char buff[256];

sprintf(buff, "Select * from %s where InstanceName='%s' ", class_name,
instance_name);

// For example, query for print queues that

// have more than 10 jobs

HRESULT hres = pSvc->ExecQuery(

bstr_t("WQL"),

bstr_t(buff),

WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,

NULL,

&pEnumerator);


in C# i am using the ManagementObject and ManagementSearcher and disposing
both of them at the end (i can provide the code you want).


Could it be some problems (bugs maybe) in the WMI enumeration implementation
?
Could it be som probs regarding decoupled providers ?

Meanwhile, I will continue to test as I try to find a pattern.

Thanks.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top