The documentation for TerminateProcess says, in part:
This function stops execution of all threads within the process and requests
cancellation of all pending I/O.
...
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.
This leaves some ambiguity about what happens if you use TerminateProcess to commit process suicide, like this:
TerminateProcess(GetCurrentProcess(), exit_code)
Logically that should be sufficient, but the documentation says that execution may continue afterwards, which is dangerous if you are calling TerminateProcess due to a bug that leaves your process in an indeterminate state.
The closest thing I have found to confirmation that waiting-on-suicide is not needed is the source code to _invoke_watson in:
C:\Program Files (x86)\Windows Kits\10\Source\10.0.10240.0\ucrt\misc\invalid_parameter.cpp
The last thing this function does is to call TerminateProcess on itself - with no wait.
It would be good to get certainty and I wanted to ask this here so that the answer can serve as a supplement to the documentation.
I got this answer from somebody offline who preferred not to post it here themselves:
My take on the user-mode documentation is that TerminateProcess is in general something that one process does to another and the documentation is written for this generality, and in this sense is correct and reasonable.
Give TerminateProcess a handle to some other process and you of course want that the call comes back to you for your continued operation.
What the documentation makes a point of is that the call's success does not mean that the other process has terminated, just that its termination has been successfully got under way.
If you rely on more than this, then you're surely doing something wrong. Investigating what exactly is reliable, or even thinking about it, has therefore never seemed very useful to me. As much as I've bothered, I've taken it all to mean that by the time TerminateProcess returns to you the other process and all its threads are already marked as terminated - literally, they have the Terminated bit set in the ETHREAD - but continues executing APCs, typically for such things as completing or cancelling I/O. Though this continued execution is greatly constrained, it may take some indefinite time. So, if you need to know that all execution is done, you watch for the process to get signalled.
Of course, to call TerminateProcess to terminate another process is a brutal thing to do, which the documentation also makes a point of saying.
Same Process
Calling TerminateProcess to terminate your own process is no less brutal. With one exception, it's very much a last resort, and even in that context, a really desperate one. Anyone who does it must have many bigger problems than what the call might return to, else surely they would call ExitProcess which explicitly does not return (but might leave the process in a deadlock).
Self-terminating via TerminateProcess introduces the case that one of the threads that's being terminated is the current thread. The post-termination APC processing is not activated for it: in the Windows 7 kernel, see PspTerminateThreadByPointer, which again makes the special case that user-mode termination of the current thread goes to the non-returning PspExitThread instead of queueing an APC for the final exit.
So, my reading is that TerminateProcess with -1 as the handle does not return, but that if you were in the kernel for the very last instructions that execute for the calling thread, you could see that other threads in your process may still execute to process APCs but yours has its APC queue drained and is about to be switched away from, never to come back. Indeed, if at this time your thread somehow has an APC to process, the kernel bug-checks!
By the way, the exception to TerminateProcess being brutal is that it's essentially the last thing that NTDLL does even for the relatively gentle self-termination via ExitProcess. It surely is well-known, yet it always surprises me, that to handle RtlExitUserProcess, NTDLL calls NtTerminateProcess twice. First, there's user-mode cleanup and a call to NtTerminateProcess giving NULL as the handle. If this succeeds, there's more user-mode cleanup, ending with a call to NtTerminateProcess giving -1 as the handle.
Well, that last call is just what you get from TerminateProcess with -1 as the handle. When you self-terminate via TerminateProcess you're just skipping past the clean-up, in both user mode and kernel mode, that you'd have got from ExitProcess. Anyway, when the TerminateProcess is, in effect, done by NTDLL as the end of ExitProcess, it's plainly expected not to return.
Related
I know you can define functions called init in any package, and these function will be executed before main. I use this to open my log file and my DB connection.
Is there a way to define code that will be executed when the program ends, either because it reaches the end of the main function or because it was interrupted ? The only way I can think of is by manually calling a deffered terminate function on each package used by main, but that's quite verbose and error prone.
The C atexit functionality was considered by the Go developers and the idea of adopting it was rejected.
From one of the related thread at golang-nuts:
Russ Cox:
Atexit may make sense in single-threaded, short-lived
programs, but I am skeptical that it has a place in a
long-running multi-threaded server.
I've seen many C++ programs that hang on exit because
they're running global destructors that don't really need to
run, and those destructors are cleaning up and freeing
memory that would be reclaimed by the operating system
anyway, if only the program could get to the exit system call.
Compared to all that pain, needing to call Flush when you're
one with a buffer seems entirely reasonable and is
necessary anyway for correct execution of long-running
programs.
Even ignoring that problem, atexit introduces even more
threads of control, and you have to answer questions like
do all the other goroutines stop before the atexit handlers
run? If not, how do they avoid interfering? If so, what if
one holds a lock that the handler needs? And on and on.
I'm not at all inclined to add Atexit.
Ian Lance Taylor:
The only fully reliable mechanism is a wrapper program that invokes the
real program and does the cleanup when the real program completes. That
is true in any language, not just Go.
In my somewhat unformed opinion, os.AtExit is not a great idea. It is
an unstructured facility that causes stuff to happen at program exit
time in an unpredictable order. It leads to weird scenarios like
programs that take a long time just to exit, an operation that should be
very fast. It also leads to weird functions like the C function _exit,
which more or less means exit-but-don't-run-atexit-functions.
That said, I think a special exit function corresponding to the init
function is an interesting idea. It would have the structure that
os.AtExit lacks (namely, exit functions are run in reverse order of when
init functions are run).
But exit functions won't help you if your program gets killed by the
kernel, or crashes because you call some C code that gets a segmentation
violation.
In general, I agree with jnml's answer. Should you however still want to do it, you could use defer in the main() function, like this: http://play.golang.org/p/aUdFXHtFOM.
I know you can define functions called init in any package, and these function will be executed before main. I use this to open my log file and my DB connection.
Is there a way to define code that will be executed when the program ends, either because it reaches the end of the main function or because it was interrupted ? The only way I can think of is by manually calling a deffered terminate function on each package used by main, but that's quite verbose and error prone.
The C atexit functionality was considered by the Go developers and the idea of adopting it was rejected.
From one of the related thread at golang-nuts:
Russ Cox:
Atexit may make sense in single-threaded, short-lived
programs, but I am skeptical that it has a place in a
long-running multi-threaded server.
I've seen many C++ programs that hang on exit because
they're running global destructors that don't really need to
run, and those destructors are cleaning up and freeing
memory that would be reclaimed by the operating system
anyway, if only the program could get to the exit system call.
Compared to all that pain, needing to call Flush when you're
one with a buffer seems entirely reasonable and is
necessary anyway for correct execution of long-running
programs.
Even ignoring that problem, atexit introduces even more
threads of control, and you have to answer questions like
do all the other goroutines stop before the atexit handlers
run? If not, how do they avoid interfering? If so, what if
one holds a lock that the handler needs? And on and on.
I'm not at all inclined to add Atexit.
Ian Lance Taylor:
The only fully reliable mechanism is a wrapper program that invokes the
real program and does the cleanup when the real program completes. That
is true in any language, not just Go.
In my somewhat unformed opinion, os.AtExit is not a great idea. It is
an unstructured facility that causes stuff to happen at program exit
time in an unpredictable order. It leads to weird scenarios like
programs that take a long time just to exit, an operation that should be
very fast. It also leads to weird functions like the C function _exit,
which more or less means exit-but-don't-run-atexit-functions.
That said, I think a special exit function corresponding to the init
function is an interesting idea. It would have the structure that
os.AtExit lacks (namely, exit functions are run in reverse order of when
init functions are run).
But exit functions won't help you if your program gets killed by the
kernel, or crashes because you call some C code that gets a segmentation
violation.
In general, I agree with jnml's answer. Should you however still want to do it, you could use defer in the main() function, like this: http://play.golang.org/p/aUdFXHtFOM.
First off, let me start by saying that I understand all the perils of calling TerminateThread from outside a thread, instead of signaling the thread to quit by itself & wait for that to happen.
My question is, can I call TerminateThread right before the app quit. There's a 100% guarantee that the app will quit at that very moment. Do I risk to incur a memory leak in this case? Or anything that should prevent me from calling that API in this particular situation?
PS. I want to call it to let the application quit faster. It is too long to explain, but I need this app to quit ASAP upon a certain condition. (The app is a screensaver and should close as soon as a user moves the mouse.)
TerminateThread will probably just make things worse, since that will orphan critical sections (and if you're really unlucky, it will be the heap critical section or the loader critical section). If you really want to get out of dodge as fast as possible, just TerminateProcess yourself. Mind you, this bypasses all DLL_PROCESS_DETACH and global destructors, but you did say you wanted to exit as fast as possible.
if I have a handle to some windows process which has stopped (killed or just ended):
Will the handle (or better the memory behind it) be re-used for another process?
Or will GetExitCodeProcess() for example get the correct result forever from now on?
If 1. is true: How "long" would GetExitCodeProcess() work?
If 2. is true: Wouldn't that mean that I can bring down the OS with starting/killing new processes, since I create more and more handles (and the OS reserves memory for them)?
I'm a bit confused about the concept of handles.
Thank you in advance!
The handle indirectly points to an kernel object. As long as there are open handles, the object will be kept alive.
Will the handle (or better the memory behind it) be re-used for another process?
The numeric value of the handle (or however it is implemented) might get reused, but that doesn't mean it'll always point to the same thing. Just like process IDs.
Or will GetExitCodeProcess() for example get the correct result forever from now on?
No. When all handles to the process are closed, the process object is freed (along with its exit code). Note that running process holds an implicit handle to itself. You can hold an open handle, though, as long as you need it.
If 2. is true: Wouldn't that mean that I can bring down the OS with starting/killing new processes, since I create more and more handles (and the OS reserves memory for them)?
There are many ways to starve the system. It will either start heavily swapping or just fail to spawn a new process at some point.
Short answer:
GetExitCodeProcess works until you call CloseHandle, after what the process object will be released and may be reused.
Long answer:
See Cat Plus Plus's answer.
I'm having trouble which boils down to wishing CreateProcess were StartProcess. The trouble is that there are circumstances under which CreateProcess returns true when it created the process but the system could not start the process. For example, CreateProcess will succeed even if one of the launchee's imports cannot be resolved.
There are probably a dozen suggestions one could make depending on what exactly I hope to accomplish by having launched this process. However, I'm afraid none of those suggestions is likely to be useful because I'm not hoping to acccomplish anything in particular by having launched this process.
One example suggestion might be to call WaitForSingleObject against the process handle and then GetExitCodeProcess. But I can't wait for the process to exit because it might stick around forever.
Another example suggestion might be to call WaitForInputIdle, which would work well if I hoped to communicate with the launchee by means of a window I could reasonably expect the launchee to create. But I don't hope that and I can't reasonably expect that. For all I know, the launchee is a console process and/or will never have a message queue. As well, I can't afford to wait around (with heuristic intent) to find out.
In fact, I can't assume anything about the launchee.
To get a better idea of how I'm thinking here, let's look at the flip side of the issue. If the process doesn't start, I want an error code that tells me how I might advise the user. If the imports all resolved and the main thread realizes it's about to jump into the CRT startup code (or equivalent), and the error code I get back is ERROR_SUCCESS, great! But I'm actually disinterested in the launchee and merely wish to provide a good user experience in the launcher.
Oh, and one more thing: I want this to be simple. I don't want to write a debugger. :-)
Ideas?
One example suggestion might be to call WaitForSingleObject against the process handle and then GetExitCodeProcess. But I can't wait for the process to exit because it might stick around forever.
Why don't you wait for the process handle for some reasonable time. If the timer expires before the handle is signaled, you can presume the process is up and running. If the handle is signaled first, and the exit code is good, then you can presume it ran and completed successfully.
In case you haven't seen it, the CreateProcess vs started problem was mentioned in Raymond Chen's blog.
Honestly, if you're not willing to accept heuristics (like, "it hasn't ended with a failure code after three seconds, therefore we assume all is well") then you're going to have to write a 'debugger', by which I mean inspect the internals of the launched process.
This question has gone so long without an answer that I suspect it's safe to conclude that the answer is: "You can't."