Can TerminateThread terminate a thread from another process? - c++

In my Windows service application I may resort to calling TerminateThread API on some of the threads in my process. (Note that I do so only as a last resort measure when a thread fails to quit in a "normal fashion" using signaling mechanism and thread synchronization techniques.) What I've noticed in the event log submitted by a customer is that very rarely TerminateThread may throw the STATUS_INVALID_THREAD exception, which happens only when that API is called on a thread belonging to a threadpool.
Since I know for sure that none of my threads are started from a threadpool, the thread that my call to TerminateThread attempts to close must be coming from another process. This could happen only due to a race condition where my thread handle is closed first and then is passed again to the TerminateThread API while the OS reuses it for some other thread in another process.
So my question is, since my service is running with sufficiently high privileges (as localService) can TerminateThread API in this situation inadvertently terminate some thread belonging to another process? And if yes, how can I prevent this (apart from finding the race-condition, that I'm doing now)?

Let's let the docs speak for themselves:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms686717(v=vs.85).aspx
Do not use TerminateThread():
TerminateThread is a dangerous function that should only be used in the most extreme cases. You should call TerminateThread only if you know exactly what the target thread is doing, and you control all of the code that the target thread could possibly be running at the time of the termination. For example, TerminateThread can result in the following problems:
[...]
You can terminate any thread, as long as you have a handle with sufficient privileges:
A thread cannot protect itself against TerminateThread, other than by controlling access to its handles. The thread handle returned by the CreateThread and CreateProcess functions has THREAD_TERMINATE access, so any caller holding one of these handles can terminate your thread.

Note that I do so only as a last resort measure when a thread fails to quit in a "normal fashion" using signaling mechanism and thread synchronization techniques.
That is a case where you cannot call TerminateThread. You can only call TerminateThread if you have precise control over the thread you are terminating and its full cooperation. If the thread fails to quit in the normal fashion, then you have lost control over the thread, the very opposite of the required conditions under which you can call TerminateThread.
If a process has lost control over one of its threads, the process cannot be saved. This is a fundamental property of threads -- they do not provide isolation of anything but flow control.

If you must do this you can do it like this.
All you need to start is the thread handle.
You call the first function with thread handle as input using the "undocumented" NtQueryInformationThread() function with the ThreadQuerySetWin32StartAddress argument, you get the StartAddress of the thread. More reading # NTInternals.
It calls NTQueryInformationThread by function address after getting the address via GetProcAddress. Then it calls it with the ThreadQuerySetWin32StartAddress argument, getting the StartAddress of the thread.
Then you call the second function which loops through all the threads via CreateToolHelp32Snapshot and compares against the supplied StartAddress. It calls TerminateThread once it finds it.
enum THREADINFOCLASS
{
ThreadQuerySetWin32StartAddress = 9,
};
typedef NTSTATUS(__stdcall * f_NtQueryInformationThread)(HANDLE, THREADINFOCLASS, void*, ULONG_PTR, ULONG_PTR*);
ULONG_PTR GetThreadStartAddress(HANDLE hThread)
{
auto NtQueryInformationThread = reinterpret_cast<f_NtQueryInformationThread>(GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtQueryInformationThread"));
if (!NtQueryInformationThread)
return 0;
ULONG_PTR ulStartAddress = 0;
NTSTATUS Ret = NtQueryInformationThread(hThread, ThreadQuerySetWin32StartAddress, &ulStartAddress, sizeof(ULONG_PTR), nullptr);
if (NT_FAIL(Ret))
return 0;
return ulStartAddress;
}
bool TerminateThreadByStartaddress(ULONG_PTR StartAddress)
{
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
if (hSnap == INVALID_HANDLE_VALUE)
return false;
THREADENTRY32 TE32 = { 0 };
TE32.dwSize = sizeof(THREADENTRY32);
BOOL Ret = Thread32First(hSnap, &TE32);
while (Ret)
{
HANDLE hTempThread = OpenThread(THREAD_ALL_ACCESS, FALSE, TE32.th32ThreadID);
if (!hTempThread)
{
Ret = Thread32Next(hSnap, &TE32);
continue;
}
if (StartAddress == GetThreadStartAddress(hTempThread))
{
TerminateThread(hTempThread, 0);
CloseHandle(hTempThread);
CloseHandle(hSnap);
return true;
}
CloseHandle(hTempThread);
Ret = Thread32Next(hSnap, &TE32);
}
CloseHandle(hSnap);
return false;
}
Credits to my friend Broihon, I didn't write this code but have used it before.

Use undocumented NTSYSAPI NTSTATUS NTAPI NtTerminateThread(IN HANDLE ThreadHandle, IN NTSTATUS ExitStatus); from http://undocumented.ntinternals.net where ThreadHandle is result from OpenThread MS function and ExitStatus set to whatever you want.

Related

Why Sleep() on Main function stop all threads?

Why does Sleep() stop all created threads? I want to create a thread but keep the Main function in sleep until the thread finishes.
bool _finished = false;
void testcount(void *p){
int i = 0;
while(i<=30){
i++;
std::cout<<i<<"\n";
Sleep(1000);
}
_finished = true;
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved){
HANDLE test = NULL;
test = CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)testcount, NULL, NULL, NULL);
if(test)
std::cout<<"test thread created";
CloseHandle(test);
while(!_finished)
Sleep(1000);
return true;
}
I am trying it now like this, but the program just never finishes, because while with Sleep stops the thread. I don't want to return anything on Main while thread not finished. Any solution?
Calls to DllMain are serialised by Win32.
All new threads start by calling DllMain (with thread attach flag), and the call the method passed to CreateThread.
Therefore your thread is waiting to call DllMain, which cannot happen until your first thread leaves DllMain.
As commenter John Sheridan notes Raymond Chen's blog post from 2007 is a really good explanation.
PS. for correct C/C++ library initialisation you should be using _beginthread or _beginthreadex rather than CreateThread directly.
The new thread is blocked because your main thread does not leave DllMain, as described in Richard's answer.
Your code also contains a data race and has undefined behavior even after this deadlock is fixed. The new thread writes to _finished, the main thread reads from _finished, concurrently. You could try to use std::atomic<bool> instead of bool to fix this, assuming availability of C++11, or you could use Win32 primitives for thread synchronization.
Changes for standard solution using std::atomic<bool>:
#include <atomic>
std::atomic<bool> finished_{false};
// Rest remains the same

c++ implementing semaphore on my own

let's pretend there are no libraries that provide semaphores for C++. I wrote this:
#include <vector>
#include <Windows.h>
class Semaphore {
HANDLE mutexS; // provides mutex in semaphore rutines
std::vector<HANDLE> queue; // provides FIFO queue for blocked threads
int value; // semaphore's value
public:
Semaphore(int init=1);
~Semaphore();
void wait();
void signal();
};
Semaphore::Semaphore(int init) {
value = init;
queue = std::vector<HANDLE>();
mutexS = CreateMutex(0,0,0);
}
Semaphore::~Semaphore() {
CloseHandle(mutexS);
}
void Semaphore::signal() {
WaitForSingleObject(mutexS, INFINITE);
if (++value <= 0) {
HANDLE someOldThread = queue.front();
ResumeThread(someOldThread);
queue.erase(queue.begin());
CloseHandle(someOldThread);
}
ReleaseMutex(mutexS);
}
I would like to know why this implementation of wait() doesn't work:
void Semaphore::wait() {
WaitForSingleObject(mutexS, INFINITE);
if (--value < 0) {
HANDLE thisThread = GetCurrentThread();
queue.push_back(thisThread);
ReleaseMutex(mutexS);
SuspendThread(thisThread );
}
else
ReleaseMutex(mutexS);
}
And this one works:
void Semaphore::wait() {
WaitForSingleObject(mutexS, INFINITE);
if (--value < 0) {
HANDLE thisThread = GetCurrentThread();
HANDLE alsoThisThread;
DuplicateHandle(GetCurrentProcess(), thisThread, GetCurrentProcess(), &alsoThisThread, 0, 0, DUPLICATE_SAME_ACCESS);
queue.push_back(alsoThisThread);
ReleaseMutex(mutexS);
SuspendThread(alsoThisThread);
}
else
ReleaseMutex(mutexS);
}
What exactly happens in each case? I've been banging my head over it for a lot of time now. The first implementation of wait, which doesn't work, makes my program block (well, it probably blocks some thread forever). The 2nd implementation works like a charm. What gives ? Why do I need to duplicate thread handles and block the duplicate ?
MSDN helps a lot here ;)
GetCurrentThread returns a pseudo-handle which is a constant for "the current thread":
A pseudo handle is a special constant that is interpreted as the current thread handle.
So when you push it in the queue, you are always pushing a constant that says "the current thread", which is obviously not what you want.
To get a real handle, you have to use DuplicateHandle
If hSourceHandle is a pseudo handle returned by GetCurrentProcess or GetCurrentThread, DuplicateHandle converts it to a real handle to a process or thread, respectively.
A final note: I suppose you are implementing this as a "test" right? Because there are several potential problems.. A very good learning exercise would be to dig them out. But you should not use this in production code.
Out of curiosity: if you want to experiment a little more, the "canonical" way of implementing semaphore with mutexes is to use two mutexes: see here
MSDN documentation for GetCurrentThread has the answer (accents are mine):
The return value is a pseudo handle for the current thread.
A pseudo handle is a special constant that is interpreted as the current thread handle. The calling thread can use this handle to specify itself whenever a thread handle is required.
...
The function cannot be used by one thread to create a handle that can be used by other threads to refer to the first thread. The handle is always interpreted as referring to the thread that is using it. A thread can create a "real" handle to itself that can be used by other threads, or inherited by other processes, by specifying the pseudo handle as the source handle in a call to the DuplicateHandle function.

Closing timers handle from the working thread

best way to ask a question is to first show an example:
this is how i create a timer in c++:
if (FALSE == CreateTimerQueueTimer(&m_hSampleStarvationTimer,
m_hSampleStarvationTimerQueue,
(WAITORTIMERCALLBACK)TsSampleStarvationTimeBomb_Static,
(LPVOID)this,
dwDueTime,
0,
WT_EXECUTEONLYONCE))
once the following callback is triggered(TsSampleStarvationTimeBomb_Static), i try to kill both the queue handle and timer's handle inside that particular thread.
void CALLBACK CCaptureChannel::TsSampleStarvationTimeBomb_Static(LPVOID lpArg, BOOLEAN TimerOrWaitFired)
{
HRESULT hr;
BOOL bHandleDeletion = FALSE;
CCaptureChannel* pCaptureChannel = (CCaptureChannel*)lpArg;
ATLASSERT(pCaptureChannel);
bHandleDeletion = DeleteTimerQueueTimer(pCaptureChannel->m_hSampleStarvationTimerQueue, pCaptureChannel->m_hSampleStarvationTimer, NULL);
bHandleDeletion = DeleteTimerQueue(pCaptureChannel->m_hSampleStarvationTimerQueue);
my question is: is it valid? i read over MSDN that the following deletion functions may return i/o errors which shouldn't concern me too much. their termination will be executed once the callback thread turns signled, automatically.
am i right?
Thanks!
DeleteTimerQueueEx will cancel and delete all timers associated with the queue as soon as all timer callbacks complete, so a single call to DeleteTimerQueueEx will suffice. You don't need the call to DeleteTimerQueueTimer. If you call it from within the callback as you currently have in your code, you must pass NULL as the CompletionEvent parameter to avoid deadlocking.

A kind of thread pool

I used to call CreateThread() for all my threads, and WaitForMultipleObjects(), an leave the routine.
To get somewhat faster code, I'd like to do a kind of thread pool. My thread pools are sometimes created, later used multiple times, and later destroyed (ie., there is not a single pool created at the begining of the program). Each thread in my thread pool call the same routine with different parameters, the number of threads is constant, and they always need to be launched at the same time.
What I do is as follows :
DWORD WINAPI runFunction(LPVOID p) {
Thread* = (Thread*) p;
while(true) {
WaitForSingleObject(thread->awakeEvenHandle, INFINITE);
thread->run();
SetEvent(thread->SleepingEventHandle);
SuspendThread(thread->handle);
}
return 0;
}
void ExecuteThreads(std::vector<Thread*> &threads) {
HANDLE* waitingEvents = new HANDLE[threads.size()];
for (int i=0; i<threads.size(); i++) {
if (threads[i]->handle == NULL) {
threads[i]->AwakeEventHandle = CreateEvent(NULL, true, false, "Awake");
threads[i]->SleepingEventHandle = CreateEvent(NULL, true, false, "Sleeping");
threads[i]->handle = CreateThread(NULL, 0. runFunction, (void*) threads[i], CREATE_SUSPENDED, NULL);
}
ResumeThread(threads[i]->handle);
ResetEvent(threads[i]->SleepingEventHandle);
SetEvent(threads[i]->AwakeEventHandle);
waitingEvents[i] = threads[i]->SleepingEventHandle;
}
WaitForMultipleObjects( threads.size(), waitingEvents, TRUE, INFINITE);
}
My class Thread has a destructor which calls CloseHandle for the HANDLEs SleepingEventHandle and AwakeEventHandle, and for the thread handle. The function Thread::run() is pure virtual, and it's up to the coder to inherit the Thread for an actual run() implementation.
As it, the code doesn't work . One reason is that when I don't need this pool anymore, the destructors of the Threads are called, but the runFunction cannot exits and this crashes (the pointer "thread" has been destroyed but is still used the the function). There are probably many other problems with my code.
How would you do it, in a simple manner ? Is-there an easy fix ? What problems will I encounter with this code ?
Thanks!
Why do you have to deal with such low level api functions? Have a look at boost::thread and boost::thread_group. Also there is a thread pool implementation works with boost::thread.
Now if your threads work for a short period of time, your system will have remarkable overhead with creating and signaling all those threads and events. ppl Task Parallelism or tbb::task are definitely the ways to go.

WaitForSingleObject problem

Read the problem carefully first.
There is a worker thread which gets spawned from a CreateInstance of CTest class. Here is the prototype of the class. hThread is the handle to thread and hEventShutdown is the event used to shutdown thread when program exits. WaitForShutdown is the public function which is used to signal hEventShutdown and wait on handle to thread till thread exits gracefully. WaitForShutdown is invoked from Exit of Application.
//pseudocode
CTest
{
public:
CTest* CreateInstance();
static threadproc(void *pv);
void WaitForShutdown();
public:
HANDLE hThread;
HANDLE hEventShutdown;
}
void CTest::CTest* CreateInstance()
{
// spawn a thread, pass 'this' pointer to thread , use beginthreadex
hThread = beginthreadex ( threadproc, this );
}
unsigned int CTest::threadproc( void *pv)
{
Ctest *ptest = (Ctest*)pv;
do
{
HANDLES hArray[2] = { pv->hEventShutdown, someotherhandle }
dwResult = Waitformultipleobjects( hArrary , 2);
if ( dwResult == WAIT_OBJECT_0)
delete pTest; // since it is allocated dynamically ( This is required due to some known reasons in my code)
if(dwResult == WAIT_OBJECT_0 + 1)
Doprocessing(); //DoProcessing when other thread signal someotherhandle
}while (1)
void CTest::WaitForShutdown()
{
SetEvent ( hEventShutdown);
WaitForSingleObject ( hThread,INFINITE);
}
void CTest::~CTest()
{
Closehandle(hThread)
Closehandle(hEventShutdown);
}
Now if you look at the code carefully, you will find that event is signaled from WaitForShutdown function, thread comes out of WaitForMultipleOjbects and deletes pointer of CTest. It means destructor of CTest is invoked which will obviously close thread handle ( hThread). But WaitForSingleObject from WaitForShutdown is actually waiting on thread handle. So here behavior will be undefined ( I think so, you can correct me if I am wrong). Another problem is destructor of Ctest is invoked when WaitForSingleObject is waiting on its member hThread which is not correct. I can not remove delete pTest from thread since it has to be there due to some reasons.
How will you suggest the solution to the above ?
Couple of Solution which I can think of :
I can keep thread handle in another map but I dont want to do it.
I can copy thread handle to some local variable before WaitForSingleObject in WaitForShutdown and will wait on it. Don;t know is it right ? you tell me.
Or I will use Duplicatehandle API to get reference of existing thread handle before WaitForSingleObject and wait on it. Dont know is it correct. Dont know if will the duplicate handle be alive after CloseHandle on original.
I will keep thread ID, get thread handle from thread ID and keep waiting on thread handle in WaitForShutdown. This looks more elegant but I do not know is there any way to get handle from thread id.
Correct me.
Your feedback appreciated.
The simplest way to handle this would be to simply delete the thread from WaitForShutdown, after WaitForSingleObject returns. This ensures all the handles you need - and more importantly, the object itself - remain alive to the end.
I have run this piece as is. Seems it works, and it doesn't crash.
Strangely that we can call CloseHandle(hthread), before we go out of WaitforSingleObject(hThread,INFINITE).
Of course, "academic" way to join thread is firstly WaitForSingleObject(hThread,INFINITE) than CloseHandle(hThread). So that is my suggestion - do in this way.
I don't have to add anymore.