Kill child process with cleanup - c++

Is there a way to kill my app's child process and perform it's cleanup(calling deconstructors and atexit functions), similarly to exit(exit_code), but on another process?

If you are on windows, you probably start your child processes by CreateProcess, which has a PROCESS_INFORMATION as the last parameter.
CreateProcess on MSDN
Process Information on MSDN
Option 1:
This process information contains a handle to the process started in the hProcess member.
You can store this handle and use it to kill your child processes.
Insert
You probably want to send WM_CLOSE and / or WM_QUIT?
to "cleanly" end the process:
Here is a KB Article on what to do KB how to cleanly kill win32 processes
** End Insert**
Option 2:
Here is an discussion on how to properly kill a process tree: Terminate a process tree on windows

There's no simple Win32 API for that kind of thing. The OS doesn't care what language your program's source code was written in, the compiled program appears to it as just a sequence of CPU instructions plus data.
The cleanest way would be to establish some kind of a communication channel between the processes (e.g. via shared memory) and simply request process termination.
You can achieve the same by starting the child process as a debugged process and then using debug APIs to alter the child's behavior, but that's too intrusive and not very straightforward to implement.

Related

linux driver check process is alive

I have a simple linux module for work with interruptions.
I send the signal to the my process pid every time when have interraption.
But how i can check the PID is alive or not?
I tryed use find_task_by_vpid in a interraption handler function.
But after that some times kernel is crashed.
NIP [c003ba9c] find_task_by_vpid+0x2c/0x4cfind_task_by_vpi d[ 782.391934] Unable to handle kernel
So now i get find_task_by_vpid only one time.
And it's work ok.
But when i kill my process like a "kill -9" my core is crashed.
Please, help me
PIDs are not a reliable to identify a process. PIDs may be reused, so if your destination process terminates (for whatever reason), its PID may be reused, without your kernel module getting notice for that. So:
Don't use PIDs for communicating with processes!ยน
Use file operations for communication between kernel and user space. Either in the form of a character or block device in /dev or as an entry in procfs /proc or in the sysfs /sys.
Have the user space process open the file; your kernel module offers a set of file operation handler functions (fops). When the process terminates, all file descriptors are closed, and the close fop of your kernel module gets called.
1: As a matter of fact, PIDs are unreliable everywhere and their use for anything should be avoided. The only sitation in which a PID is somewhat reliable is inside the parent process, that forked off that PID, since wait-s will prevent the process to completely vanish until the parent dealt with its demise. But anyone else on the system has no information about that.

how to handle your windows application being force closed?

if a user decides to force close my application(like through the task manager) is there a way i can quickly execute some clean up code before the application closes? i'm coding in c++ btw
It depends on how the process is instructed to close. It is possible to do this upon graceful exit, but not for anything forcefully closed.
If the process is closed via TerminateProcess or ExitProcess, you won't be able to perform any graceful cleanup. TerminateProcess is how Task Manager and utilities like Sysinternals pskill end a target process. ExitProcess is called within a process but is not typically used to exit.
If the process has a message pump on one thread (typically the first thread in the process) and no other threads running that are running code whose lifetimes are independent of activity in that thread, then a WM_QUIT message will signal that the process should close (semantically, that the app should close, your process might conceivably stick around for a while for other reasons), and you can run cleanup code upon receiving the message. Depending on your needs, in a windowed app you might consider performing cleanup operations as early as WM_CLOSE or WM_DESTROY.
If you have written code in a DLL, there are notifications that you can handle in DllMain that will allow you to perform last-chance cleanup (DLL_PROCESS_DETACH), which can potentially cover the case of a process exiting without having a message pump. However, this is not a great way to perform cleanup for code that strictly relies on any C/C++ runtime (or any other DLL), as the runtime might be unloaded first.
Last, for any graceful close where you control what runs in WinMain or main, you can always do whatever cleanup you need to do before either function returns, sending control back to the windows subsystem. This is preferred and usually safest for most application needs.
If you are using a message pump, handle the WM_QUIT message.
Also: What is the difference between WM_QUIT, WM_CLOSE, and WM_DESTROY in a windows program?
EDIT
Im sorry, I read over the fact that you want to handle termination, eg by the task manager.
This might help you though: How to catch event when Task manager kill your C++ application

Linux fork function compared to Windows' CreateProcess - what gets copied?

I am porting Windows application to Linux. I use CreateProcess on Windows to run child processes and redirect all standard streams (in, out, error). Streams redirect is critical, main process sends data to children and receives theirs output and error messages. Main process is very big one with a lot of memory and threads, and child processes are small ones. On Linux I see that fork function has similar functionality as CreateProcess on Windows. However, manual says that fork "creates parent process copy", including code, data and stack. Does it mean that if I create copy of a huge process that uses 1 GB of memory just to run a very simple command line tool that uses 1 MB of memory itself, I will need to fist duplicate 1 GB of memory with fork, and then replace this 1 GB with 1 MB process? So, if I have 100 threads it will be required to have 100 GB of memory to run 100 processes that need just 100 MB of memory to run? Also what about other threads in parent process that "don't know" about fork execution, what will they do? What fork function does "under the hood" and is it really effective way to create a lot of small child processes from huge parent?
When you call fork() then initially only your VM is copied and all pages are marked copy-on write. Your new child process will have a logical copy of your parent processes VM, but it will not consume any additional RAM until you actually start writing to it.
As for threads, fork creates only one new thread in the child process that resembles a copy of the calling thread.
Also as soon as you call any of the exec family of calls (which I assume you want to) then your entire process image is replaced with a new one and only file descriptors are kept.
If your parent process has a lot of open file descriptors then I suggest you go through /proc/self/fd and close all file descriptors in the child that you don't need.
fork basically splits your process into two, with both parent and child processes continuing at the instruction after the fork function call. However, the return value value in the child process is 0, whilst in the parent process it is the process id of the child process.
The creation of the child process is extremly quick since it uses the same pages as the parent. The pages are marker as copy-on-write (COW) so that if either process changes the page then the other won't be affected. Once the child process exists it usually calls one of the exec functions to replace itself with a image. Windows doesn't have an equivilant to fork, instead the CreateProcess call only allows you to start a new process.
There is an alternative to fork called clone which gives you much more control over what happens when the new process is started. For example you can specify a function to call in the new process.
The copies are "copy-on-write", so if your child process does not modify the data, it will not use any memory besides that of the father process. Typically, after a fork(), the child process makes an exec() to replace the program of this process with a different one, then all the memory is dropped anyway.
I haven't used CreateProcess, but fork() is not an exact copy of the process. It creates a child process, but the child starts its execution at the same instruction in which the parent called fork, and continues from there.
I recommend taking a look at Chapter 5 of the Three Easy Pieces OS book. This may get you started and you might find the child spawning call you're looking for.
The forked child process has almost all the parent facility copied: memory, descriptors, text etc. The only exception is parents' threads, they are not copied.

Monitoring processes of the Windows OS using the C language

I want to make an application in C or C++ which have to monitor some specific processes. How can I make it possible in C?
You said that you have tomaonitor "some specific processes". If your application started the processes, you can extract the process handles from the PROCESS_INFORMATION structure (field hProcess) you passed to the CreateProcess function. If the process you want to track has been launched in some different way, you need the process' ID (PID), and use it as third argument of OpenProcess to obtain an handle. So you can use the WaitForSingleObject or WaitForMultipleObjects functions to wait for the process completion. Optionally you can obtain the process' exit code with the GetExitCodeProcess function.
There are other ways by which an application can start a new process (e.g. by the _system() library function), but I strongly suggest to use CreateProcess directly in your code, since you can control the child process' behaviour completely (e.g. you can select the priority, pass stdin/stdout/stderr handles, decide the startup window's characteristics...).
Suggested example:
http://msdn.microsoft.com/en-us/library/ms682512%28VS.85%29.aspx
You start a process in Windows with the CreateProcess() function. It returns a HANDLE to the process in PROCESS_INFORMATION.hProcess. That handle will be signaled when the process terminates, allowing you to keep track of its lifetime. Use WaitForSingleObject() or WaitForMultipleObjects() to do so. There's a code sample available here...
Before you write your own, have you looked at Process Monitor v2.8?
Process Monitor is an advanced
monitoring tool for Windows that shows
real-time file system, Registry and
process/thread activity. It combines the features of two legacy
Sysinternals utilities, Filemon and
Regmon, and adds an extensive list of
enhancements including rich and
non-destructive filtering,
comprehensive event properties such
session IDs and user names, reliable
process information, full thread
stacks with integrated symbol support
for each operation, simultaneous
logging to a file, and much more.
Boost.Process
sample for Win32 Platform.

Terminate all (grand)children when terminating a child process

I will jump right in, to be brief and descriptive:
C++, Windows API
I am creating child processes using CreateProcess to run external (command-line) applications. I have built in a time-out, and if the child process has not returned normal execution by that time, I wish to force termination on that child process.
Ideally, I would like for that child process to act the same as if it had called ExitProcess, or as if a Ctrl+C was sent to its console (which calls ExitProcess from the default console control handler).
My solution so far has been the use of TerminateProcess to kill the child forcefully. This does force the child to terminate immediately, but unfortunately if that child spawned any children of its own they are left to run until their "natural" completion.
Is there a way to tell the child process to call ExitProcess, or to force all of the child's children to also terminate when TerminateProcess is called?
These external applications are beyond my control, and as such I can not modify them to provide a custom work-around.
Assume no knowledge of grand-child processes (names/pids/etc) that would allow me to manually call TerminateProcess on grand-child processes individually. Although this could be done by manually enumerating all processes, mapping process relationships, and tracking all processes, I do not consider this a valid solution except as the absolute last resort.
Thank you for your time.
You can use Job objects to kill all the processes as a unit. You create a job object via the CreateJobObject API, and assign a process to it with AssignProcessToJobObject. New processes created by a process in a job object belong to the same job object by default. Calling TerminateJobObject will terminate all associated processes in the job object.