How do you kill a completly locked up thread?

W

Willy Denoyette [MVP]

Ben Voigt said:
Only if it's using a shared heap...

I'l talking about real world applications (.NET or not), calling into
arbitray code, how would a caller know what allocator is getting used? I'm
talking about Windows applications calling into library code, that allocates
from the process heap, CRT heap or from the COM heap, that is, allocates
from the heap manager (ntdll). You can't safely kill threads that are
executing in these libraries.

But you can use a kernel mutex instead, then it'll be marked as abandoned
and you can recover.

Again, I'm calling into arbitrary code, say I'm calling into Winsock library
like the OP is doing.... and this library is using CS all the way down.

My point was that .NET in particular does a bunch of stuff that is not
abort safe. This is far from saying that .NET is the only library that
isn't abort safe, but there is nothing inherently unsafe about Win32
itself.

What do you call Win32?
A thread that executes arbitrary (native code libraries, whatever) code
cannot safely be killed (using TerminateThread ) , that's why the CLR
refuses to kill a thread (using TerminateThread ) that currently runs in
"unmanaged" code, the CLR waits for the thread to return into managed to
checks whether a thread abort has been issued, gracefully aborting the
thread when it's the case (not using TerminateThread !).
Again, it's unsafe to call Win32's TerminateThread, unless you know it's
not.

Willy.
 
B

Ben Voigt [C++ MVP]

Willy Denoyette said:
I'l talking about real world applications (.NET or not), calling into
arbitray code, how would a caller know what allocator is getting used? I'm
talking about Windows applications calling into library code, that
allocates from the process heap, CRT heap or from the COM heap, that is,
allocates from the heap manager (ntdll). You can't safely kill threads
that are executing in these libraries.

I wasn't talking about arbitrary code. I was challenging your statement
"this has nothing to do with .NET, this is about Windows". It is not
possible to write abort safe code in .NET. Of course not all code written
without .NET is abort safe, but the act of using .NET prevents being abort
safe, whereas the act of using Windows does not. So this isn't exclusive to
..NET, but it isn't applicable to Windows in general like it is to .NET.

BTW you can use the heap manager (ntdll) with private heaps. You could not
safely free such a heap after a thread was aborted while allocating from it,
but it would not block other threads either.
 
W

Willy Denoyette [MVP]

Ben Voigt said:
I wasn't talking about arbitrary code. I was challenging your statement
"this has nothing to do with .NET, this is about Windows". It is not
possible to write abort safe code in .NET. Of course not all code written
without .NET is abort safe, but the act of using .NET prevents being abort
safe, whereas the act of using Windows does not. So this isn't exclusive
to .NET, but it isn't applicable to Windows in general like it is to .NET.

BTW you can use the heap manager (ntdll) with private heaps. You could
not safely free such a heap after a thread was aborted while allocating
from it, but it would not block other threads either.


I was talking about arbitrary code, and here I mean - calling arbitrary code
from whatever environment you see fit( .NET or other) on Windows, that's why
I keep saying that it has nothing to do with .NET.

Whenever you call *TerminateThread* to kill a thread that actually runs code
you didn't *completely* implement yourself, you are in danger. That's why
MSDN says that "TerminateThread" is dangerous API, you should never call it
unless you know exactly what the target thread is actually doing, which is
exactly the point of this whole thread, you *never* know what the thread is
doing when running arbitrary code. Some say that this service (invoked by
TerminateThread) should never have been exposed to user code)

Note also, that "private" based on the heap manager (ntdll) have the same
issue, the heap manager protects it's internal structures with critical
sections when you are allocating/de-allocating, you don't control the heap
manager don't you?.
Killing a thread when the heap manager runs in a critical section, will most
likely corrupt the heap and deadlock whenever another thread tries to
allocate/de-allocate from the same heap.

Simply things like statics and global variables, TLS, FLS etc... are
allocated on the heap, creating a thread (from kernel32) in windows calls
the heap manager (ntdll), several hundred times, to allocate from the
process heap, dynamic module loading/unloading allocate from the process
heap, kernel32 and ntdll are the first modules loaded by the OS loader when
you create a process, no single Win32 process can live without them.
You aren't going to rewrite all these Win32 DLL's and runtime libraries, so
that they use your own heap manager, don't you?

You could build your own private heap manager on top of the VM Manager (like
the CLR's memory allocator) , but just like the "Heap Manager " you'll have
to protect your internal structures with a CS, if you want to handle
allocations from multiple threads. So, you are back at square zero, nor will
it solve the other possible issues related to TerminateThread.

Willy.
 

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