Thread not terminated while application is terminated under Delphi - windows

assume I have a thread which is still running when the application is terminating
(This thread can not terminate because it waits for a Windows api call to return
and that can be long...)
What happens to the thread if the application is closed ?
Can it raise an exception (I'm under Delphi) ?

I'd say that an exception is very plausible. When you call Application.Terminate this will lead to the following sequence of events:
A call to PostQuitMessage.
Application.Terminated being set to True.
Application.Run returning.
System.Halt is called.
Exit procedures are run, specifically DoneApplication which will tear down Application and all components that it owns. Hmm, better hope your thread does not access anything owned by Application.
FinalizeUnits is called. Uh-oh. Memory manager is shut down, and lots more beside.
ExitProcess is called. Now your thread is killed.
Your thread will carry on running until the call to ExitProcess. If it executes any code at all that would be affected by the calls to DoneApplication and FinalizeUnits, then you should expect problems.

Related

Killing a process that is hanging on disk IO

I've got an SSD that is failing. Some of its data can't be read anymore.
I would like to know which files are affected.
I've created some small program that uses regular functions (CreateFile, ReadFile) to read files.
The program has some watchdog thread that monitors the thread that issues the IO functions. If they take too long, the thread marks somewhere the file is damaged and tries to kill the IO thread and the process.
My issue is using TerminateThread and TerminateProcess does not kill the thread/process. It hangs there, forever, until I log out.
Trying to kill using TaskManager also fails, of course (it used to use NtTerminateProcess, I don't know what it does nowadays).
Does anyone know a way that would kill my process?
According to the Doc: TerminateProcess function
This function stops execution of all threads within the process and
requests cancellation of all pending I/O. The terminated process
cannot exit until all pending I/O has been completed or canceled. When
a process terminates, its kernel object is not destroyed until all
processes that have open handles to the process have released those
handles.
When a process terminates itself, TerminateProcess stops execution of
the calling thread and does not return. Otherwise, TerminateProcess is
asynchronous; it initiates termination and returns immediately. If you
need to be sure the process has terminated, call the
WaitForSingleObject function with a handle to the process.
I suggest you could try to use Job Objects.

Does DebugActiveProcessStop close handles?

According to the documentation, ContinueDebugEvent will close handles after EXIT_THREAD_DEBUG_EVENT and EXIT_PROCESS_DEBUG_EVENT.
What happens to those handles in the following case:
DebugSetProcessKillOnExit(FALSE); // Keep the process running after stopping the debugger.
DebugActiveProcessStop(dwProcessId);
The process and threads will still be running, and the documentation doesn't mention anything about handles. Can I assume that they will be closed for me?
yes, DebugActiveProcessStop call CloseAllProcessHandles before do actual stop debugging via DbgUiStopDebugging call. the CloseAllProcessHandles close all opened thread and process handles. it list stored in thread TEB - this mean that call must be done only from the same thread which call other debug api (such WaitForDebugEvent). unfortunately i also not view confirmation of this in documentation, only research. this screenshot from win10

ExitProcess behaviour in Windows in relation to atexit handlers

I want to be able to catch any attempts of executing exit()/ExitProcess()/TerminateProcess() or any other such calls.
I thought about registering a handler with atexit(). This works fine for normal program termination (return from main()) or exit() calls (regardless of the thread that calls exit()), but ExitProcess() and TerminateProcess() bypass the handler I registered.
ExitProcess() documentation states:
Note that returning from the main function of an application results
in a call to ExitProcess.
But the observed behaviour is at least different in this regard.
Is there a method of registering a handler for process exit/termination what will always be called (except for external calls to TerminateProcess(), unhandled exceptions thrown by one of my threads or __failfast() calls, I'm guessing these are really impossible to catch).
There is the dirty option of hooking ExitProcess(), but I'd rather not do that.
EDIT: just so this is clear: I'm interested in my own process, not monitoring / controlling another process.
There is a Kernel Mode Event a device driver can subscribe to in order to get notifications of terminations of processes. This is preferred over trying to inject a DLL into processes for API hooks due to the myriad number of internal and external ways that process may end.

creating window in child thread in vc++

I want to create a window and show some image display (like animation based on SetTimer()) on window created using CreateWindow() function. But it should be created on separate thread and should remain alive until user closes this. I tried but was unsuccessful.
EDITED
I just googled I found this link How To Create Windows in a Multithreaded Application but one thing i want to know when Window Procedure get invoked. if it is invoked by system then how i can call it from my child thread.
Windows (represented by HWNDs) in Windows have a thread affinity. Their WindowProc is always invoked in the context of the thread they are created with.
As such, they are a convenient way to serialize calls between threads as the PostMessage and SendMessage APIs can be called from any thread in the application, but the WindowProc will get executed in the context of the original creating thread.
Because WM_TIMER messages posted to message queues are the mechanism by which SetTimer works, again you need to be careful when calling SetTimer in a multithreaded app - The timer messages will be processed by the calling thread (if the hwnd parameter is NULL) or the window's thread.
You also, as a result, have to be careful to put a message loop on every thread that might create windows, or want to process timers.
Keep your user-interface on the main Windows thread. Setting a timer using the Windows API doesn't require an additional thread (as your WndProc will get the timer message WM_TIMER).
Even if you have a long running task to perform that might necessitate the use of an additional thread, keep the window on the main thread, do your work in the worker-thread and post back to the main thread with updates.

Intermittent issues with Win32 named events

Experiencing intermittent issues, related to named events when processes are running in different user contexts: WaitForSingleObject (and WaitForMultipleObjects too) for such event handle fails with WAIT_FAILED (GetLastError returns 6 - Invalid handle value).
We have an application to schedule tasks on Windows machines under user accounts, and issue happens after some tasks are completed.
Service part of application (JobManager) starting executable (JobLeader) under user account (CreateProcessAsUser) to run user task, and waiting for named event to be signaled.
Manual reset named event is created by JobLeader in the "Global\" namespace and signaled when user task is completed.
JobManager waiting in the loop, calling WFMO(WaitForMultipleObjects) with delay of 10 seconds, to see if named event or JobLeader process handle are signaled.
Periodically named event handle, opened by JobManager through OpenEvent API call, causes WFMO (WFSO is also called after to identify which handle is broken) to return WAIT_FAILED, with error code 6 - "Invalid handle value".
After reopening the event, this error may gone, or may not - WFMO may again returns WAIT_FAILED because of invalid handle value.
Interesting, that it may pass few dozens tasks without this error, and then - sequentially few tasks have it. Tasks used for testing are identical - just a cmd.exe script, dumping environment.
Anyone have ideas about this?
Regards,
Alex
Do you create the event in your JobManager and then open it in the 'JobLeader'? If not, how do you communicate the event handle (and/or name) between the two processes?
My gut tells me it's a race condition...

Resources