Console exception after calling PerformanceCounterCategory methods

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

I am attempting to create a custom performance counter category for use by an
application I am developing. I have found, however, that after calling any of
several of the static PerformanceCounterCategory methods, the next attempt to
write to the Console fails with a System.IO.IOException (_message = "the
handle is invalid", _COMPlusExceptionCode = -532459699, _HResult =
-2147024890).

I am developing using Visual Studio 2003 v 7.1.3088 and .NET Framework v
1.1.4322 SP1.

The following code reliably reproduces the problem on my system:

try
{
Console.WriteLine("Beginning Performance Counter Installation Test");
if (PerformanceCounterCategory.Exists("testcategory"))
{
PerformanceCounterCategory.Delete("testcategory");
Console.WriteLine("Called Delete for existing performance category");

if (PerformanceCounterCategory.Exists("testcategory"))
Console.WriteLine("Performance category still exists!");
else
Console.WriteLine("Performance Category successfully deleted.");
}
else
Console.WriteLine("Category does not yet exist.");

CounterCreationData ccd = new CounterCreationData("testcounter",
"Test counter", PerformanceCounterType.NumberOfItems32);
CounterCreationDataCollection ccdc = new CounterCreationDataCollection();
ccdc.Add(ccd);
Console.WriteLine("Initialized counter creation data collection.");
PerformanceCounterCategory.Create("testcategory", "Test category", ccdc);
Console.WriteLine("Created category and counters");

PerformanceCounterCategory[] allCategories =
PerformanceCounterCategory.GetCategories();
Console.WriteLine("Retrieved all performance counter categories");
}
catch(Exception e)
{
int i = 1;
}

By commenting out various parts of the above code, I have established that
this problem occurs:

* In the PerformanceCounterCategory.Exists call, but only if the return
value was false (if the category _does_ exist, it's fine.
* In the PerformanceCounterCategory.Create call
* In the PerformanceCounterCategory.GetCategories call.

In all these cases, the PerformanceCounterCategory functions do actually
execute successfully - the correct value is returned, category is created and
categories are listed. It's only the next attempt to write to the standard
output that goes splat.

It looks a lot like something is closing the standard output stream... I
have tried redirecting the standard output to something other than the
console buffer, and got the same result.

A serious side-effect of the problem is that if you attempt to use
InstallUtil to run a PerformanceCounterInstaller, the IOException as
InstallUtil attempts to write to the console after actually performing the
installation causes the installation to be rolled back (even though the
counters _were_ actually successfully installed).

As an even better side effect: while using InstallUtil to run an installer
that included a ServiceInstaller, ServiceProcessInstaller and
PerformanceCounterInstaller, this exception tripped the debugger, then
somehow deleted half the CurrentControlSet entries in the registry
(everything before my custom performance category in the alphabet) during the
rollback. This quite effectively rendered my development machine so much junk
(vmware is your friend...).

So, does anyone have any insight to offer on this issue? I really don't want
to have to choose between my performance counters and my console output, much
less between the performance counters and the installation!

I have looked at the description for the KB830297 fix, but am uncertain as
to its applicability, since we have no J# code at all. Please help!
 
Some extra information I forgot...

This problem is only occurring on Windows 2003 - it does not occur on my
Windows XP machine.

I am running the console application as a local Administrator in both cases.

Sydney said:
I am attempting to create a custom performance counter category for use by an
application I am developing. I have found, however, that after calling any of
several of the static PerformanceCounterCategory methods, the next attempt to
write to the Console fails with a System.IO.IOException (_message = "the
handle is invalid", _COMPlusExceptionCode = -532459699, _HResult =
-2147024890).

I am developing using Visual Studio 2003 v 7.1.3088 and .NET Framework v
1.1.4322 SP1.

The following code reliably reproduces the problem on my system:

try
{
Console.WriteLine("Beginning Performance Counter Installation Test");
if (PerformanceCounterCategory.Exists("testcategory"))
{
PerformanceCounterCategory.Delete("testcategory");
Console.WriteLine("Called Delete for existing performance category");

if (PerformanceCounterCategory.Exists("testcategory"))
Console.WriteLine("Performance category still exists!");
else
Console.WriteLine("Performance Category successfully deleted.");
}
else
Console.WriteLine("Category does not yet exist.");

CounterCreationData ccd = new CounterCreationData("testcounter",
"Test counter", PerformanceCounterType.NumberOfItems32);
CounterCreationDataCollection ccdc = new CounterCreationDataCollection();
ccdc.Add(ccd);
Console.WriteLine("Initialized counter creation data collection.");
PerformanceCounterCategory.Create("testcategory", "Test category", ccdc);
Console.WriteLine("Created category and counters");

PerformanceCounterCategory[] allCategories =
PerformanceCounterCategory.GetCategories();
Console.WriteLine("Retrieved all performance counter categories");
}
catch(Exception e)
{
int i = 1;
}

By commenting out various parts of the above code, I have established that
this problem occurs:

* In the PerformanceCounterCategory.Exists call, but only if the return
value was false (if the category _does_ exist, it's fine.
* In the PerformanceCounterCategory.Create call
* In the PerformanceCounterCategory.GetCategories call.

In all these cases, the PerformanceCounterCategory functions do actually
execute successfully - the correct value is returned, category is created and
categories are listed. It's only the next attempt to write to the standard
output that goes splat.

It looks a lot like something is closing the standard output stream... I
have tried redirecting the standard output to something other than the
console buffer, and got the same result.

A serious side-effect of the problem is that if you attempt to use
InstallUtil to run a PerformanceCounterInstaller, the IOException as
InstallUtil attempts to write to the console after actually performing the
installation causes the installation to be rolled back (even though the
counters _were_ actually successfully installed).

As an even better side effect: while using InstallUtil to run an installer
that included a ServiceInstaller, ServiceProcessInstaller and
PerformanceCounterInstaller, this exception tripped the debugger, then
somehow deleted half the CurrentControlSet entries in the registry
(everything before my custom performance category in the alphabet) during the
rollback. This quite effectively rendered my development machine so much junk
(vmware is your friend...).

So, does anyone have any insight to offer on this issue? I really don't want
to have to choose between my performance counters and my console output, much
less between the performance counters and the installation!

I have looked at the description for the KB830297 fix, but am uncertain as
to its applicability, since we have no J# code at all. Please help!
 
Hi

Based on my test on a windows 2003 machine, I can not reproduce the
problem. Here is my test code for your reference.
If I have any misunderstanding, please feel free to post here.

using System;
using System.IO;
using System.Diagnostics;
namespace ConsoleApplication1
{
class Class1
{
public static void Test()
{
try
{
Console.WriteLine("Beginning Performance Counter Installation Test");
if (PerformanceCounterCategory.Exists("testcategory"))
{
PerformanceCounterCategory.Delete("testcategory");
Console.WriteLine("Called Delete for existing performance category");

if (PerformanceCounterCategory.Exists("testcategory"))
Console.WriteLine("Performance category still exists!");
else
Console.WriteLine("Performance Category successfully deleted.");
}
else
Console.WriteLine("Category does not yet exist.");

CounterCreationData ccd = new CounterCreationData("testcounter",
"Test counter", PerformanceCounterType.NumberOfItems32);
CounterCreationDataCollection ccdc = new
CounterCreationDataCollection();
ccdc.Add(ccd);
Console.WriteLine("Initialized counter creation data collection.");
PerformanceCounterCategory.Create("testcategory", "Test category",
ccdc);
Console.WriteLine("Created category and counters");

PerformanceCounterCategory[] allCategories =
PerformanceCounterCategory.GetCategories();
Console.WriteLine("Retrieved all performance counter categories");
}
catch(Exception e)
{
int i = 1;
Console.WriteLine(e.ToString());
}
}
[STAThread]
static void Main(string[] args)
{
for(int i=0;i<10;i++)
Test();
Console.WriteLine("TestOK");
}
}
}


Best regards,

Peter Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
 
Peter,

If I run your code, I get an exception on the first call to
Console.WriteLine("Category does not yet exist."); if the category does not
exist, or at the call to Console.WriteLine("Performance Category successfully
deleted."); if I manually create the category before running the console app.

The exception info available in the debugger is:

- e {"The handle is invalid.\r\n" } System.Exception
+ [System.IO.IOException] {System.IO.IOException} System.IO.IOException
System.Object {System.IO.IOException} System.Object
_className null string
_COMPlusExceptionCode -532459699 int
_exceptionMethod <undefined value> System.Reflection.MethodBase
_exceptionMethodString null string
_helpURL null string
_HResult -2147024890 int
_innerException { } System.Exception
_message "The handle is invalid.\r\n" string
_remoteStackIndex 0 int
_remoteStackTraceString null string
_source null string
+ _stackTrace {System.Array} System.Object
_stackTraceString null string
_xcode -532459699 int
_xptrs 0 int
HelpLink null string
HResult -2147024890 int
InnerException { } System.Exception
Message "The handle is invalid.\r\n" string
Source "mscorlib" string
StackTrace " at System.IO.__Error.WinIOError(Int32 errorCode, String
str)\r\n at System.IO.__ConsoleStream.Write(Byte[] buffer, Int32 offset,
Int32 count)\r\n at System.IO.StreamWriter.Flush(Boolean flushStream,
Boolean flushEncoder)\r\n at System.IO.StreamWriter.Write(Char[] buffer,
Int32 index, Int32 count)\r\n at System.IO.TextWriter.WriteLine(String
value)\r\n at System.IO.SyncTextWriter.WriteLine(String value)\r\n at
System.Console.WriteLine(String value)\r\n at
ConsoleApplication1.Class1.Test() in
d:\\develop\\performancecounterinstaller\\class1.cs:line 24" string
+ TargetSite {System.Reflection.RuntimeMethodInfo} System.Reflection.MethodBase


After stepping through the dissasembly, the call stack at the point where
the content in the console window suddenly vanishes is:
system.dll!System.Diagnostics.PerformanceMonitor.GetData(string item =
"Global") + 0x12b bytes
system.dll!System.Diagnostics.PerformanceCounterLib.GetPerformanceData(string item = "Global") + 0xaa bytes
system.dll!System.Diagnostics.PerformanceCounterLib.get_CategoryTable() +
0xe7 bytes
system.dll!System.Diagnostics.PerformanceCounterLib.CategoryExists(string
category = "testcategory") + 0xf bytes
system.dll!System.Diagnostics.PerformanceCounterLib.CategoryExists(string
machine = ".", string category = "testcategory") + 0x44 bytes
system.dll!System.Diagnostics.PerformanceCounterCategory.Exists(string
categoryName = "testcategory", string machineName = ".") + 0x19c bytes
system.dll!System.Diagnostics.PerformanceCounterCategory.Exists(string
categoryName = "testcategory") + 0x14 bytes
PerformanceCounterInstaller.exe!ConsoleApplication1.Class1.Test() Line 13 +
0xc bytes C#
PerformanceCounterInstaller.exe!ConsoleApplication1.Class1.Main(string[]
args = {Length=0}) Line 49 + 0xb bytes C#

All contents of the open console window vanish when stepping over:
0000012b call dword ptr ds:[7B353E60h]
I am unable to step into this call to extract any more detail.

Do you have any ideas for things I could check to work out why this is
occurring? My system is running Windows 2003 Server SP1 on VMWare 5.0. I have
tried reverting to a known-good snapshot, but the problem is still seen.

:

<snipped test code/>
 
Hi

For your scenario, I think you may need to contact MSPSS directly which
will create dump on your machine to further analysis.
Because the .NET symbols is not public, without symbols, the call stack may
be full of assembly code which is unreadable.

Best regards,

Peter Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
 
Back
Top