Determining Thread objects in a process

P

Pete

Is there any way that anyone knows of to get a list of the Thread objects
for a running process from within the process? I don't mean ProcessThreads
returned by the Process in System.Diagnostics, but the Thread objects
themselves.

Here's my problem:

On shut down, under some conditions, and not reliably, our app hangs inside
the .NET framework (1.1). In releasing an ActiveX control, eventually deep
in the framework, GC.WaitForPendingFinalizers() is called and the app hangs.

We're using a third party library that has a thread running constantly that
basically calls GC.Collect() and GC.WaitForPendingFinalizers() every second.
Yeah, I know this is bad, but they have it there for a reason and I'm not
sure I can do anything about that.

What I'd like to do is, at the very least, rule out that thread as the
problem, but my suspicion is that the app is hanging on shutdown because
GC.WaitForPendingFinalizers() is being called from 2 threads in the same
process simultaneously. That's just a guess, but that's where I am.

What I'd like to do is, programmatically, find their thread, and kill it,
before our app gets to the call that results in the hang. Their thread has a
Name that I can identify, if I can get a list of threads.

So I really just need this, at the moment, for diagnostic purposes to either
confirm that that is in fact the problem or that it's not the problem.

So, is there any way for me to get the Thread object with the Name property
(the ProcessThread does not have the name because ProcessThread is a wrapper
for the API Thread functions and Name is a managed property).

VS.NET manages to do it somehow in the Threads window. It can get both the
thread ID # as well as its managed name. I'm willing to use unmanaged code
to get at the information. Clearly there's some way to get to it if VS.NET
can do it. I just can't seem to figure out how it does it.

Thanks.

Pete
 
C

Chris Mullins [MVP]

From what I remember of how GC works, I don't think your assumption is
correct.

If memory serves, there's a single thread in the CLR whose responsabilities
it is to run Finalizers. Finalizers ONLY get run from that thread. If you
have a finalizer that blocks, or worse, deadlocks, no other finalizer is
every going to be called. This isn't a thread you really have any control
over, and if it's blocked, your whole appdomain (the whole process?) is just
screwed. Objects that have finalizers are added to the finalization queue,
and the finalizer thread walks that queue on a regular basis - no amount of
calling GC.Collection from any number of threads is really going to change
how that works.

Your best bet is to get your application hung, then use ADPlus to generate a
minidump. Load the dump into WinDbg + Son of Strike, type !threads, and
start debugging from there.

There's a little bit more detail on how to do that here:
http://www.coversant.com/Coversant/Blogs/tabid/88/EntryID/28/Default.aspx

I suspect you're in for a rough ride...
 

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