From: Joe Eddy on
So...I've been trying for days to track down a handle leak in one of
my applications...it's a very slow leak, but it's in an application
that is meant to run continuously and is currently making use restart
it every few weeks.

When I use !htrace -diff in windbg to try to track it down, what I
find is a bunch of these:

--------------------------------------
Handle = 0x00000a80 - OPEN
Thread ID = 0x000007fc, Process ID = 0x00000bb4

0x79f7582b: mscorwks!CLREvent::CreateManualEvent+0x00000027
0x79f03e9d: mscorwks!Thread::AllocHandles+0x00000077
0x79f04b47: mscorwks!Thread::CreateNewOSThread+0x0000007c
0x79f04ac3: mscorwks!Thread::CreateNewThread+0x0000009e
0x79f91adf: mscorwks!ThreadNative::StartInner+0x0000015c
0x79f91c48: mscorwks!ThreadNative::Start+0x000000a6
0x792d6b4c: mscorlib_ni+0x00216b4c
0x00e8f89b: +0x00e8f89b
0x00e8f49a: +0x00e8f49a
0x00e88d02: +0x00e88d02
--------------------------------------

I have a function that creates two threads periodically, but I can't
figure out why they'd be leaky...I've tried reproducing the leak using
a simplified program but have so far been unsuccessful.

Anyone ever seen handles like this being leaked that might have any
hints at what I should be looking at?
From: Joe Eddy on
> Put back the pieces you took out one at a time, and see which piece
> brings back the problem.

I haven't taken pieces out one at a time...the program I'm working on
is complex enough to make that approach prohibitive, which is why I
started using windbg to try to get the stack for the code that is
creating the leaked handles...unfortunately all I'm getting are memory
addresses because it seems like the MS symbol server is missing
symbols for one of their dlls.

The stack traces I am getting look like they point toward something
that calls CreateNewOSThread...which I kind of assumed may be related
to my two periodic "new Thread()" calls...so I tried creating a
smaller program that does something similar and reproduce the leak but
haven't had any luck.

I was kind of hoping someone might see this that might know what other
kind of calls might be doing CreateNewOSThread under the hood that I
can try to look at.

I also have some Timers triggering code, and also external programs
running code through .NET remoting (all framework version 2.0), and
I'm guessing that either of those might result in a call to
CreateNewOSThread, as well, so I'll look into those more when I get a
chance.

Does anyone know if there's a way to get more information on what code
cause the handle to be created? The stack I get out of windbg isn't
very helpful...it would be nice if I could drill down into my managed
code.

From: not_a_commie on
The ProcessExplorer tool will tell you what handles are open. I'd
start with that. I have a vague memory of FXCop telling you which
items are IDisposable. I'm sure you could find some tool that would do
that. You need to make sure you dispose of every disposable object.
The Timer objects are pretty scary in general. It gets tricky to sort
out your code as soon as the timer queue is backed up. At the place I
work we replaced them all with our own loops that measure the
execution time and then potentially sleep the remainder of the
interval. That plan worked much better. The CreateManualEvent item in
your stack is interesting. Are you creating any of those in your code?
I also suggest the 14day trial of Red Gate's Memory Profiler.
From: Joe Eddy on
Yeah I've gone through and made sure I'm disposing of every disposable
object.
The program has a few persistent timers that don't run very often, and
the ones that DO run often are actually just "fire once" timers that
get reset once the processing is finished, so I don't think it's a
problem with the timer queue getting backed up (alhough the problem
might still be related to the timers). I actually used to have
separate loops in persistent threads instead of timers, but ran into
some issues that I thought using timers could fix...maybe not!
I don't create manual events in my code...that call stack is buried
somewhere that I haven't yet been able to track down.
I'll take a look at Red Gate's Memory Profiler.
From: Joe Eddy on
> I'll take a look at Red Gate's Memory Profiler.

Tried using this...it doesn't seem to track handles, though. I can
verify that I don't have a straightforward memory leak...I don't have
new objects being allocated that are not being cleaned up.

My guess is that these handles are associated with one of my
persistent objects, but I'll have to track down which.

I've read about Monitor creating event handles that are "sticky" to
the synchronization object, so maybe something similar is going on
here?