I have a thread that to some operations and it needs to be alive until a flag says otherwise.
I use PsCreateSystemThread to create the thread and then use ObReferenceObjectByHandle to get ETHREAD object reference to waiting for the thread to terminate before the driver unloaded using KeWaitForSingleObject.
The function that creates the thread and retrieves a reference to it:
ntStatus = PsCreateSystemThread(
&hThread,
(ACCESS_MASK)0, NULL,
(HANDLE)0, NULL,
ThreadRoutine,
(PVOID)pThreadData
);
if (!NT_SUCCESS(ntStatus))
{
return ntStatus;
}
ntStatus = ObReferenceObjectByHandle(
hThread,
THREAD_ALL_ACCESS,
NULL,
KernelMode,
(PVOID*)&ptThreadObject,
NULL
);
if (!NT_SUCCESS(ntStatus))
{
bStopThread = TRUE;
ptThreadObject = NULL;
return ntStatus;
}
The thread routine:
LARGE_INTEGER liSleepTime;
while (FALSE == bThread)
{
liSleepTime.QuadPart = 1000 * RELATIVE_MILLISECOND;
KeDelayExecutionThread(KernelMode, FALSE, (&liSleepTime));
ExAcquireFastMutex(&fmMutex);
//DO SOMTHING
ExReleaseFastMutex(&fmMutex);
}
PsTerminateSystemThread(STATUS_SUCCESS);
The unload driver function:
if (NULL != ptThreadObject)
{
bStopThread = TRUE;
KeWaitForSingleObject(
(PVOID)ptThreadObject,
Executive,
KernelMode,
FALSE,
(&liTimeOut));
ObDereferenceObject((PVOID)ptThreadObject);
ptThreadObject= NULL;
}
I need this thread to run all the time.
Is there a way to check if the thread is terminated prematurely? (If it was done by PsTerminateSystemThread I can add a 'boolean' and set it before calling PsTerminateSystemThread to terminate the thread).
One more question:
I terminated the thread at the start of its routine and waited for 20 seconds before calling ObReferenceObjectByHandle and it didn't fail.
ntStatus = PsCreateSystemThread(
&hThread,
(ACCESS_MASK)0, NULL,
(HANDLE)0, NULL,
ThreadRoutine,
(PVOID)pThreadData
);
if (!NT_SUCCESS(ntStatus))
{
return ntStatus;
}
// The ThreadRoutine calling PsTerminateSystemThread first and terminate.
liSleepTime.QuadPart = 20000 * RELATIVE_MILLISECOND;
KeDelayExecutionThread(KernelMode, FALSE, (&liSleepTime));
ntStatus = ObReferenceObjectByHandle(
hThread,
THREAD_ALL_ACCESS,
NULL,
KernelMode,
(PVOID*)&ptThreadObject,
NULL
);
if (!NT_SUCCESS(ntStatus))
{
bStopThread = TRUE;
ptThreadObject = NULL;
return ntStatus;
}
Why does ObReferenceObjectByHandle succeed and not fail? -The thread is long gone.
Thanks.
Why does ObReferenceObjectByHandle succeed and not fail? -The thread
is long gone.
but why it must fail ?? ObReferenceObjectByHandle simply return returns the corresponding pointer to the object's body. ETHREAD in your case. the state of object - not play any role here. terminated thread or not absolute unrelated. until you have handles or referenced pointers to thread body structure (ETHREAD) - the object will be not freed. so, if hThread is valid handle - ObReferenceObjectByHandle must succeed.
How to determine if thread terminated?
very easy - simply wait on it say via KeWaitForSingleObject, which you already done. because thread objects are themselves a type of dispatcher object, when thread terminated, it set to signal state and KeWaitForSingleObject return.
if (ptThreadObject)
{
bStopThread = TRUE;
KeWaitForSingleObject(
ptThreadObject,
Executive,
KernelMode,
FALSE,
0);
ObDereferenceObject(ptThreadObject);
}
note - you must set Timeout to 0 for waits indefinitely until the thread terminated (dispatcher object is set to the signaled state). also you not need cast ptThreadObject to PVOID - it is already pointer. (PVOID)ptThreadObject is not error, but superfluous and unnecessary code.
Is there a way to check if the thread is terminated prematurely?
the operation system and i not understand what you mean under prematurely. check that thread terminated we can via wait on it. but prematurely can have sense only in context of your code. say you can set different thread exit status via PsTerminateSystemThread and than (after thread terminated) get this exist status via PsGetThreadExitStatus . if thread still running the PsGetThreadExitStatus return STATUS_PENDING. this routine can be partially used to check thread state too - if it return any status different from STATUS_PENDING - thread is terminated. but if it return STATUS_PENDING - unclear - or thread still running, or thread exist via PsTerminateSystemThread(STATUS_PENDING). of course use STATUS_PENDING as exist status is bad idea and never must be used. under this condition you can determine thread state (running/terminated) with PsGetThreadExitStatus too, but this routine not wait. but your driver logic require wait when thread terminated, and only after this we can unload driver. so only KeWaitForSingleObject (or another wait function) is correct solution here. if thread can exist in different ways - use different exit status in call PsTerminateSystemThread and get it back via PsGetThreadExitStatus after thread terminated (so after KeWaitForSingleObject)
however call to PsTerminateSystemThread is optional - you can simply return from ThreadRoutine - in this case system yourself call PsTerminateSystemThread(STATUS_SUCCESS); - so in your code call PsTerminateSystemThread(STATUS_SUCCESS); also superfluous and unnecessary code. you need call PsTerminateSystemThread only in case you want return status different from STATUS_SUCCESS and check return status after thread terminated. note that windows itself not interpret and use thread exit status. it simply store it in ETHREAD object. if you not query and use this status - does not matter what its exit status.
also liSleepTime.QuadPart = 1000 * RELATIVE_MILLISECOND; line you can out from loop - set before loop, if you use constant timeout.
also we can not wait for thread termination in driver unload at all, if use special thread entry point in asm code. obviously that driver must not be unloaded, until thread is running. for this exist 2 solution - one is wait in driver unload routine, for all drivers thread termination. but exist and another - add reference to driver object, when we create thread, and de-reference driver object, when thread exit.
so define global variable:
PDRIVER_OBJECT gDriverObject;
in DriverEntry initialize it: gDriverObject = DriverObject;
and start thread in next way:
ObfReferenceObject(gDriverObject);
NTSTATUS status = PsCreateSystemThread(
&hThread,
0, NULL,
0, NULL,
ThreadRoutine,
pThreadData
);
if (!NT_SUCCESS(status))
{
ObfDereferenceObject(gDriverObject);
}
and on thread exit need call ObfDereferenceObject(gDriverObject);. but after ObfDereferenceObject(gDriverObject); we already can not return to driver code - it can be already unloaded. so this call can not be done from c/c++ code. in user mode exist FreeLibraryAndExitThread, but in kernel mode no analog of this api. only solution - implement thread entry point in asm code - this entry call c/c++ thread routine and finally jmp (but not call) to ObfDereferenceObject.
define your c/c++ proc as
void NTAPI _ThreadRoutine(PVOID pv)
{
// not call PsTerminateSystemThread here !!
}
code for x64 and c (ml64 /c /Cp $(InputFileName) -> $(InputName).obj)
extern _ThreadRoutine : PROC
extern gDriverObject : QWORD
extern __imp_ObfDereferenceObject : QWORD
_TEXT segment 'CODE'
ThreadRoutine proc
sub rsp,28h
call _ThreadRoutine
add rsp,28h
mov rcx,gDriverObject
jmp __imp_ObfDereferenceObject
ThreadRoutine endp
_TEXT ENDS
end
code for x86 and c (ml /c /Cp $(InputFileName) -> $(InputName).obj)
.686
extern _gDriverObject:DWORD
extern __imp_#ObfDereferenceObject#4:DWORD
extern __ThreadRoutine : PROC
_TEXT SEGMENT
_ThreadRoutine proc
mov eax,[esp]
xchg eax,[esp+4]
mov [esp],eax
call __ThreadRoutine
mov ecx,_gDriverObject
jmp __imp_#ObfDereferenceObject#4
_ThreadRoutine endp
_TEXT ENDS
END
with this you can not wait fot working thread exit - simply signal to him terminate (bStopThread = TRUE;) and return from driver unload.
Related
I wish to create a Thread that will always run until I force him to be close.
I programming in c language, and uses the library windows.h
adding my code of creating thread:
HANDLE thread;
DWORD threadID;
thread = CreateThread(NULL, 0, infinitePlay, (void*)*head, 0, &threadID);
if (thread)
{
// doing some work or just waiting
}
In one word (short answer), you need to call the BOOL TerminateThread(HANDLE hThread, DWORD dwExitCode); see microsoft docs in the link term_thread function and pass to it in the hThread param the return thread from CreateThread function in your case it is thread
for long answer
consider the thread function ThreadRoutine below:
#include <windows.h>
DWORD WINAPI ThreadRoutine(void* data) {
/*Creates a thread to execute within the virtual address space of the calling process.
this function will be passed later as a functio pointer to CreateThread which will be the the application-defined function to be executed by the thread.*/
return 0;
}
Now this is the CreateThread function from microsoft_docs
HANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes,
SIZE_T dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress,
__drv_aliasesMem LPVOID lpParameter,
DWORD dwCreationFlags,
LPDWORD lpThreadId
);
Function arguments
lpThreadAttributes: If lpThreadAttributes is NULL, the handle cannot be inherited by child processes.
dwStackSize: The initial size of the stack, in bytes. The system rounds this value to the nearest page. If this parameter is zero, the new thread uses the default size for the executable.
**lpStartAddress**:
A pointer to the application-defined function to be executed by the thread. This pointer represents the starting address of the thread. in our case its the ThreadRoutine.
lpParameter: A pointer to a variable to be passed to the thread. we can pass in void* what ever we like to pass since its a generic pointer.
dwCreationFlags: The flags that control the creation of the thread.
lpThreadId: A pointer to a variable that receives the thread identifier. If this parameter is NULL, the thread identifier is not returned.
return value
If the function succeeds, the return value is a handle to the new thread. If the function fails, the return value is NULL.
Killing the thread we have created:
BOOL TerminateThread(HANDLE hThread, DWORD dwExitCode);
TerminateThread is used to cause a thread to exit. When this occurs, the target thread has no chance to execute any user-mode code. DLLs attached to the thread are not notified that the thread is terminating. The system frees the thread's initial stack.
If the function succeeds, the return value is nonzero.
If the function fails, the return value is zero.
So after reviewing all CreateThread arguments, we will use the the form below:
int main() {
HANDLE t_thread = CreateThread(NULL, 0, ThreadRoutine, NULL, 0, NULL);
if (t_thread ) {
// Optionally do stuff, such as wait on the thread or ...
/*After some time lets kill or terminate the thread we have created*/
BOOL re_term =TerminateThread(t_thread , DWORD dwExitCode);
if(re_term == 0){ //failed
/*maybe you should call GetLastError function*/
}
else{
/*killed successefully*/
}
}
return 0;
}
The perfect way to run and terminate threads in Windows using C is mentioned in the answer below!
There are 2 problems I'm facing with the current implementation method :
I can't forcibly stop the thread. For some reason it still continues. For example I have a for loop, it runs a function of which this thread example is a part. When this function is called 4-5 times, I see multiple animations on the screen suggesting that the previous threads didn't stop even when I called TerminateThread function at the end of my function.
At times the thread doesn't run at all and no animation is displayed on the screen. Which is if my function code runs really fast or for some other reason, I feel like the thread is being killed before it initializes. Is there a way to wait until init of thread?
How do I fix these issues?
Correct way of terminating threads is to signal the thread and let it finish gracefully, i.e.:
(updated to use interlocked intrinsics instead of a volatile flag, as per #IInspectable's comment below)
HANDLE eventHnd;
HANDLE threadHnd;
LONG isStopRequested = 0; // 1 = "stop requested"
static DWORD WINAPI thread_func(LPVOID lpParam)
{
do
{
// wait until signalled from a different thread
WaitForSingleObject(eventHnd, INFINITE);
// end thread if stop requested
if (InterlockedCompareExchange(&isStopRequested, 0, 0) == 1)
return 0;
// otherwise do some background work
Sleep(500);
} while (true);
}
The eventHnd variable is initialized using the CreateEvent function, and the stopRequested variable is just a boolean flag you can set from your main program:
// this creates an auto-reset event, initially set to 'false'
eventHnd = CreateEvent(NULL, false, false, NULL);
InterlockedExchange(&isStopRequested, 0);
threadHnd = CreateThread(NULL, 0, Processing_Thread, NULL, 0, NULL);
So, whenever you want to tell the thread do perform a task, you will simply set the event:
SetEvent(eventHnd);
And when you want to end the thread, you will set the flag to true, signal the event, and then wait for the thread to finish:
// request stop
InterlockedExchange(&isStopRequested, 1);
// signal the thread if it's waiting
SetEvent(eventHnd);
// wait until the thread terminates
WaitForSingleObject(threadHnd, 5000);
So far I've worked with processes and threads only on Linux platform.
Now I tried to move on Windows. And I got immediately stopped on very simple program.
Can you tell me why my program doesn't write anything if I remove the line with getch?
I want my thread to finish without me pressing anything.
Thank you in advance
#include <windows.h>
#include <stdio.h>
DWORD WINAPI ThreadFunc()
{
printf("lets print something");
return 0;
}
VOID main( VOID )
{
DWORD dwThreadId;
HANDLE hThread;
hThread = CreateThread(
NULL, // default security attributes
0, // use default stack size
ThreadFunc, // thread function
NULL, // argument to thread function
0, // use default creation flags
&dwThreadId); // returns the thread identifier
// Check the return value for success.
if (hThread == NULL)
{
printf( "CreateThread failed (%d)\n", GetLastError() );
}
else
{
_getch();
CloseHandle( hThread );
}
}
If your box is relatively idle, the OS is quilte likely to signal the thread creation request to another core, so allowing the 'main' thread, (the one created by the process loader), to run on quickly. By the time your new thread gets round to calling the OS with the printf call, the main thread has already returned, the state of all threads for that process has been set to 'never run again' and a termination request queued up for it on its inter-processor core driver. The new thread is exterminated there and then and the now-redundant termination request discarded.
How can I make unknown number of child threads inside parent thread and wait for each of them one by one using win32 in C?
The parent thread life time is infinite and it is wait for request and if received any request then make a new child thread for that request e.g. like servers .
I am searching the web but I cant find anything .
Any tutorial and information appreciated .
Thanks a lot , good luck .
note :
1 . For example imagine a simple server : When a user send a request to that server the server make a new thread for that user and wait for that thread to terminated but if another user send another request the server make another thread which is completely separate from the old one and then the server must wait for the new thread separate from the old one to terminate .
2 . The main thread scan an global array with the size of constant n in the infinite loop and if find the specific value in each of array's block then run the new thread to do some operation on that block's information and then after the thread become terminate update that block's information . The parent thread life time is infinite because it has a infinite loop .
You'ld create each thread with CreateThread and store the thread handle in a dynamic list or array. If you want the main thread to recognize when a thread terminated, then you can call WaitForMultipleObjects, providing it an array with all thread handles. The return value of WaitForMultipleObjects will tell you which thread handles was signalled, so which thread terminated. Don't forget to CloseHandle the thread handle at the end.
If you just want to spawn threads and the main thread does not need to know when the threads terminate, then you can just create the threads with CreateThread and close the thread handle. The thread's resources will be freed when the thread terminates.
In your main thread you will also need to check if you receive a client request. If you have an Interface to the client where you can wait on an event, then just add the event to the event array passed to WaitForMultipleObjects. If you do not have an event like in your case 2, then you might consider calling WaitForMultipleObjects with a timeout so WaitForMultipleObjects either returns when a thread terminated or when the timeout occured. In both cases your main loop keeps running and you can check if you need to spawn another thread.
Here is some pseudo code when using an event for the client requests:
initialize empty list of thread data (thread handles and other data for each thread);
for(;;) {
create an array a big enough for the request event and for all thread handles;
a[0] = request event handle;
a[1..n] = thread handles from the list;
DWORD ret = WaitForMultiObjects(n+1, a, FALSE, INFINITE);
if(ret == WAIT_OBJECT_0) {
create thread and store it's handle and other data in the list;
}
else if(WAIT_OBJECT_0 + 1 <= ret && ret <= WAIT_OBJECT_0 + n) {
thread (ret - WAIT_OBJECT_0 - 1) terminated, do your cleanup and don't forget CloseHandle();
}
else
error occured, should not happen;
}
If you don't have an event for the client requests, then you need to poll:
initialize empty list of thread data (thread handles and other data for each thread);
for(;;) {
create an array a big enough for the request event and for all thread handles;
a[0..n-1] = thread handles from the list;
DWORD ret = WaitForMultiObjects(n, a, FALSE, your desired timeout);
if(ret != WAIT_TIMEOUT)
; // timeout occured, no thread terminated yet, nothing to do here
else if(WAIT_OBJECT_0 <= ret && ret < WAIT_OBJECT_0 + n) {
thread (ret - WAIT_OBJECT_0) terminated, do your cleanup and don't forget CloseHandle();
}
else
error occured, should not happen;
// Always check for client requests, not only in case of WAIT_TIMEOUT.
// Otherwise you might run into the situation that every time you call WaitForMultiObjects a thread ended just before the timeout occured and you only recognize it after a lot of loop runs when the last thread terminated.
if(there is a client request) {
create thread and store it's handle and other data in the list;
}
}
If you do not need to store extra data for each thread, then you can just store the thread handles and maybe already store them in a big array. Thus you could eliminate the step to build an array from the thread handle list.
Maybe yo should use the WaitForMultipleObjects function.
http://msdn.microsoft.com/en-us/library/windows/desktop/ms687025(v=vs.85).aspx
My application creates a thread and that runs in the background all the time. I can only terminate the thread manually, not from within the thread callback function.
At the moment I am using TerminateThread() to kill that thread but it's causing it to hang sometimes.
I know there is a way to use events and WaitForSingleObject() to make the thread terminate gracefully but I can't find an example about that.
Please, code is needed here.
TerminateThread is a bad idea, especially if your thread uses synchronization objects such as mutexes. It can lead to unreleased memory and handles, and to deadlocks, so you're correct that you need to do something else.
Typically, the way that a thread terminates is to return from the function that defines the thread. The main thread signals the worker thread to exit using an event object or a even a simple boolean if it's checked often enough. If the worker thread waits with WaitForSingleObject, you may need to change it to a WaitForMultipleObjects, where one of the objects is an event. The main thread would call SetEvent and the worker thread would wake up and return.
We really can't provide any useful code unless you show us what you're doing. Depending on what the worker thread is doing and how your main thread is communicating information to it, it could look very different.
Also, under [now very old] MSVC, you need to use _beginthreadex instead of CreateThread in order to avoid memory leaks in the CRT. See MSKB #104641.
Update:
One use of worker thread is as a "timer", to do some operation on regular intervals. At the most trivial:
for (;;) {
switch (WaitForSingleObject(kill_event, timeout)) {
case WAIT_TIMEOUT: /*do timer action*/ break;
default: return 0; /* exit the thread */
}
}
Another use is to do something on-demand. Basically the same, but with the timeout set to INFINITE and doing some action on WAIT_OBJECT_0 instead of WAIT_TIMEOUT. In this case you would need two events, one to make the thread wake up and do some action, another to make it wake up and quit:
HANDLE handles[2] = { action_handle, quit_handle };
for (;;) {
switch (WaitForMultipleObject(handles, 2, FALSE, INFINITE)) {
case WAIT_OBJECT_0 + 0: /* do action */ break;
default:
case WAIT_OBJECT_0 + 1: /* quit */ break;
}
}
Note that it's important that the loop do something reasonable if WFSO/WFMO return an error instead of one of the expected results. In both examples above, we simply treat an error as if we had been signaled to quit.
You could achieve the same result with the first example by closing the event handle from the main thread, causing the worker thread get an error from WaitForSingleObject and quit, but I wouldn't recommend that approach.
Since you don't know what the thread is doing, there is no way to safely terminate the thread from outside.
Why do you think you cannot terminate it from within?
You can create an event prior to starting the thread and pass that event's handle to the thread. You call SetEvent() on that event from the main thread to signal the thread to stop and then WaitForSingleObject on the thread handle to wait for the thread to actually have finished. Within the threads loop, you call WaitForSingleObject() on the event, specifying a timeout of 0 (zero), so that the call returns immediately even if the event is not set. If that call returns WAIT_TIMEOUT, the event is not set, if it returns WAIT_OBJECT_0, it is set. In the latter case you return from the thread function.
I presume your thread isn't just burning CPU cycles in an endless loop, but does some waiting, maybe through calling Sleep(). If so, you can do the sleeping in WaitForSingleObject instead, by passing a timeout to it.
What are you doing in the background thread? If you're looping over something, you can end the thread within itself by having a shared public static object (like a Boolean) that you set to true from the foreground thread and that the background thread checks for and exits cleanly when set to true.
It is a code example for thread management in the fork-join manner. It use struct Thread as a thread descriptor.
Let's introduce some abstraction of the thread descriptor data structure:
#include <Windows.h>
struct Thread
{
volatile BOOL stop;
HANDLE event;
HANDLE thread;
};
typedef DWORD ( __stdcall *START_ROUTINE)(struct Thread* self, LPVOID lpThreadParameter);
struct BootstrapArg
{
LPVOID arg;
START_ROUTINE body;
struct Thread* self;
};
Functions for the thread parent use:
StartThread() initialize this structure and launches new thread.
StopThread() initiate thread termination and wait until thread will be actually terminated.
DWORD __stdcall ThreadBootstrap(LPVOID lpThreadParameter)
{
struct BootstrapArg ba = *(struct BootstrapArg*)lpThreadParameter;
free(lpThreadParameter);
return ba.body(ba.self, ba.arg);
}
VOID StartThread(struct Thread* CONST thread, START_ROUTINE body, LPVOID arg)
{
thread->event = CreateEvent(NULL, TRUE, FALSE, NULL);
thread->stop = FALSE;
thread->thread = NULL;
if ((thread->event != NULL) && (thread->event != INVALID_HANDLE_VALUE))
{
struct BootstrapArg* ba = (struct BootstrapArg*)malloc(sizeof(struct BootstrapArg));
ba->arg = arg;
ba->body = body;
ba->self = thread;
thread->thread = CreateThread(NULL, 0, ThreadBootstrap, ba, 0, NULL);
if ((thread->thread == NULL) || (thread->thread == INVALID_HANDLE_VALUE))
{
free(ba);
}
}
}
DWORD StopThread(struct Thread* CONST thread)
{
DWORD status = ERROR_INVALID_PARAMETER;
thread->stop = TRUE;
SetEvent(thread->event);
WaitForSingleObject(thread->thread, INFINITE);
GetExitCodeThread(thread->thread, &status);
CloseHandle(thread->event);
CloseHandle(thread->thread);
thread->event = NULL;
thread->thread = NULL;
return status;
}
This set of functions is expected to be used from the thread launched by StartThread():
IsThreadStopped() - Check for the termination request. Must be used after waiting on the below functions to identify the actual reason of the termination of waiting state.
ThreadSleep() - Replaces use of Sleep() for intra-thread code.
ThreadWaitForSingleObject() - Replaces use of WaitForSingleObject() for intra-thread code.
ThreadWaitForMultipleObjects() - Replaces use of WaitForMultipleObjects() for intra-thread code.
First function can be used for light-weight checks for termination request during long-running job processing. (For example big file compression).
Rest of the functions handle the case of waiting for some system resources, like events, semaphores etc. (For example worker thread waiting new request arriving from the requests queue).
BOOL IsThreadStopped(struct Thread* CONST thread)
{
return thread->stop;
}
VOID ThreadSleep(struct Thread* CONST thread, DWORD dwMilliseconds)
{
WaitForSingleObject(thread->event, dwMilliseconds);
}
DWORD ThreadWaitForSingleObject(struct Thread* CONST thread, HANDLE hHandle, DWORD dwMilliseconds)
{
HANDLE handles[2] = {hHandle, thread->event};
return WaitForMultipleObjects(2, handles, FALSE, dwMilliseconds);
}
DWORD ThreadWaitForMultipleObjects(struct Thread* CONST thread, DWORD nCount, CONST HANDLE* lpHandles, DWORD dwMilliseconds)
{
HANDLE* handles = (HANDLE*)malloc(sizeof(HANDLE) * (nCount + 1U));
DWORD status;
memcpy(handles, lpHandles, nCount * sizeof(HANDLE));
handles[nCount] = thread->event;
status = WaitForMultipleObjects(2, handles, FALSE, dwMilliseconds);
free(handles);
return status;
}