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.
Related
I have an external library with long calculation. This library is everything, but cooperative in regard of premature stopping. It is wrapped and started within a coroutine.
I would like to kill the process from the caller side. Coroutine cancell is cooperative, so it doesn't work. Is there any way to terminate the coroutine abruptly?
A non-suspending coroutine can be abruptly killed only by killing the thread it's executing on, and Java has deprecated all methods of abruptly stopping a thread. They are deprecated for a good reason: threads aren't a unit of isolation like processes are. Aborting a thread can have arbitrary consequences on the state of the surviving process.
The cleanest option for launching long-running, non-cooperatively abortable work is to start a sub-process doing it.
I'm using the synchrounous flavor of ReadDirectoryChangesW in a thread. Everything works perfectly well.
But I'm unable to terminate the thread otherwise than calling TerminateThread from my main thread, because if there is no activity in the monitored directory, ReadDirectoryChangesW is waiting forever.
The solution with TerminateThread works, but this is kind of dirty.
Another solution would be to create a dummy file in the monitored directory which will unblock ReadDirectoryChangesW, but this is just another hack.
So is there a way to unblock/abort ReadDirectoryChangesW properly ?
You could switch to using it with a completion routine and immediately after the call to ReadDirectoryChangesW() call a wait function which puts you into an alertable wait state and also waits on an event which you use to abort the wait...
If you open the handle with FILE_SYNCHRONOUS_IO_ALERT then it is possible to use the undocumented NtAlertThread to send a signal to stop the wait.
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.
What is the difference between killing an application using the close button and ending the process from the Task Manager?
I am aware of the fact that hitting the close button posts a WM_CLOSE message in the message queue, but I don't know what happens when we kill a process from Task Manager (or any similar application like Killbox or Process Explorer).
When you click the "X" button in the title bar of an application's window, that sends the window a WM_CLOSE message. This is a "graceful" shutdown—the application processes the message, handles any necessary cleanup tasks, and can even refuse to shut down if it so desires (by returning zero in response to the message). WM_CLOSE is simply a request that the window or application terminate; the window is not destroyed until the application itself calls the DestroyWindow function.
When you press the "End Task" button in Task Manager, Windows will first try to send the application (if it is a GUI application) a WM_CLOSE message. In other words, it first asks nicely and gives the app a chance to terminate itself cleanly.*
If you fail to close in response to that initial WM_CLOSE message, the Task Manager will follow up by calling the TerminateProcess function. This function is a little bit different because it forcefully terminates the application's process and all of its threads without asking for permission from the app. This is a very harsh method of closing something, and should be used as a last resort—such as when an application is hung and is no longer responding to messages.
TerminateProcess is a very low-level function that essentially rips the user-mode part of a process from memory, forcing it to terminate unconditionally. Calling TerminateProcess bypasses such niceties as close notifications and DLL_PROCESS_DETACH. Your application does not have the ability to refuse to close, and there is no way to catch/trap/hook calls to TerminateProcess. All user-mode code in the process simply stops running for good. This is a very unclean shut down procedure, somewhat akin to jerking the computer's power plug out of the wall.
* Note that this only true if you use the "Applications" tab of Task Manager to kill the application. If you use the "Processes" tab, this step is skipped and the TerminateProcess function is called immediately. This distinction is reflected in the caption on the respective buttons. For the "Applications" tab, the button is lableled "End Task"; for the "Processes" tab, the button is labeled "End Process".
Killing the process with WM_CLOSE simply signals the process with the message and allows the target to handle the message and exit gracefully. Alternatively, the process could choose not to exit in its WM_CLOSE handler.
Killing the process via task manager will do so with TerminateProcess which is far harsher:
The TerminateProcess function is used to unconditionally cause a
process to exit. The state of global data maintained by dynamic-link
libraries (DLLs) may be compromised if TerminateProcess is used rather
than ExitProcess.
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.
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. A process cannot prevent itself from
being terminated.
If you close an application using the close button you let the application to perform necessary closing tasks if any. If you kill a process from task manager there is no chance for application to perform those tasks, you just terminate the application without informing.
I have a Process called "Agent" it spawns a new process called "Connect". This "Connect" process loads the service dll's. The "Connect" process start a sub process(cmd.exe), I would like to know if for some reasons the loaded dll's cause a hang or a crash, how to ensure that "cmd.exe" is terminated.
Use CreateProcess to spawn the new process. The involves setting up and passing in a PROCESS_INFORMATION structure: which will contain a handle to the new process (hProcess) if the call to CreateProcess works.
You can now do a WaitForSingleObject on this process handle to see when the process finishes. WaitForSingleObject allows you to timeout if the object does not trigger (i.e. process does not terminate), and hence take action (TerminateProcess I presume).