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.
Related
I'm working on a large-scale application that spawns numerous processes for dealing with various tasks. In some situations, the OS will kill one of my processes because of memory pressure. That's ok, it's entirely expected, the parent process handles this gracefully.
What I'd like to know is find out why a process was killed. If it was killed because of memory pressure, I want to respawn the treatment a little later. If it was killed for any other reason – because, say, of an assertion failure or an out of bounds memory access, I want to log and investigate.
So, here's my question: how do you find out that a child process was killed because the OS needed the memory?
Question applies to:
Windows;
MacOS;
Linux;
(for bonus points, I'm also interested in Android, but that's not my priority).
Processes are not running as root/admin.
On Linux, you can read the syslog to find out whether a process was killed by the OS. you can investigate it by reading the syslog (/var/log/messages or /var/log/syslog on some distributions) or via the dmesg command.
If you spawned the process you can also detect that it was killed with the SIGKILL(9) signal, as opposed to the SIGSEGV(11) signal that corresponds to the app crashing all by itself, and SIGINT(2)/SIGTERM(15) that means that the applications was aked to terminate gracefully.
Regarding Windows, I only know that this type of monitoring can be enabled via the Application Event Log. There's a GUI Application that can help you set it up.
When the OS intervenes in the execution of a process in order to kill, it does so via signals.
What you can do (on IX based/like platforms) is -- dmesg.
It outputs the kernel activity logs.
From there, you can identify the signal that was sent to your process.
For example this code below --
#include <stdio.h>
int main (void)
{
char *p = NULL;
printf ("\n%c", *p);
return 0;
}
Causes this obtained from dmesg --
[8478285.606105] crash.out[16830]: segfault at 0 ip 0000000000400531 sp 00007fffc373b090 error 4 in crash.out[400000+1000]
I have an .exe Program, which triggers some other files during execution.
So at a given point, the tree might become like:
Main program
-Program 1
-Program 2
-Program 3
Of all these programs I have their PID, so I am able to close them successfully. However, when a user 'brute forces the program' (read close the program manually), I am unable to close these child programs. Is there an option to trigger the closing of child-programs before the main-program itself will actually exit. (Something is for example also possible in an html-page to remind the user e.g. or they really want to leave te page).
Because, when this situation occurs, on the next run the main-program will try to start up these child-programs again, however they are already running. (And the settings of the main-program are time dependent and have to be transferred to the other child-programs on start-up to work properly)
Ideally, I would like to have a cross-platform solution, since I have to make the app available for Windows, Linux and MacOS.
Thanks for your answers.
This is an OS feature and each OS offers it in its own way. Keeping track of the PIDs does not work, for once for the reason you mention (your parent process may itself crash) and second because the child process may spawn grand-children processes of its own that needs to be tracked, and then grand-grand-children and so on.
On Windows this is handled by NT Job Objects by asking for the JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE:
Causes all processes associated with the job to terminate when the last handle to the job is closed.
The way to use it is to create the job object in the parent process and make the handle non-inheritable. Then any child process will become part of the job, but only one handle exisst (the one owned by the parent). If the parent crashes then the handle is reclaimed by the OS and this will terminate the NT job object, killing all child processes as well as any grand-child or grand-grand-child process.
On Linux (and OS X) the same functionality is achieved with process groups.
I am not aware of any cross-platform library that would abstract this into a coherent uniform API.
In Windows (7), in VC++ we can set the "process shutdown parameters" (in XP a parent process will automatically shutdown before the child) to ensure a parent process is killed BEFORE a child process, like so:
GetProcessShutdownParameters(&shutdownlevel, &shutdownflags);
SetProcessShutdownParameters(shutdownlevel+1, SHUTDOWN_NORETRY);
How to do this in C++ on Linux (gcc) ? I find a lot discussion in many forums on how to ensure a child process killed, in case a parent process dies (e.g. use of prctl on Linux), but I have found nothing on how to GUARANTEE that the parent process is killed by the OS before the child process, like the above for Windows. Maybe it is automatic in Linux ?
System shutdown in the Unix world works a bit differently.
When the system is being shut down, at first the shutdown scripts are invoked, which handle any complex or time consuming tasks, and when the scripts have run, all remaining processes are then first sent a SIGTERM signal (which kills any process that doesn't have an explicit handler), and, a few seconds later, a SIGKILL signal (which kills the process and cannot be handled).
The order in which the last part happens is undefined.
In general programs should be written so they can be shutdown by simply sending SIGTERM.
I'm guessing that you want the parent stopped before the child because the parent would simply restart the child. The proper way to avoid that is to collect the child's exit status (which you are responsible for anyway), and avoid restarting when the exit status indicates that the process ended because of being sent SIGTERM.
(You still want to restart on SIGKILL, because that is what happens to the largest process when the system runs out of memory)
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.
I am invoking several processes in my main and I can get the pid of that processes. Now I want to wait until all this processes have been finished and then clear the shared memory block from my parent process. Also if any of the process not finished and segfaulted I want to kill that process. So how to check from the pid of processes in my parent process code that a process is finished without any error or it gave broke down becoz of runtime error or any other cause, so that I can kill that process.
Also what if I want to see the status of some other process which is not a child process but its pid is known.
Code is appreciated( I am not looking for script but code ).
Look into waitpid(2) with WNOHANG option. Check the "fate" of the process with macros in the manual page, especially WIFSIGNALED().
Also, segfaulted process is already dead (unless SIGSEGV is specifically handled by the process, which is usually not a good idea.)
From your updates, it looks like you also want to check on other processes, which are not children of your current process.
You can look at /proc/{pid}/status to get an overview of what a process is currently doing, its either going to be:
Running
Stopped
Sleeping
Disk (D) sleep (i/o bound, uninterruptable)
Zombie
However, once a process dies (fully, unless zombied) so does its entry in /proc. There's no way to tell if it exited successfully, segfaulted, caught a signal that could not be handled, or failed to handle a signal that could be handled. Not unless its parent logs that information somewhere.
It sounds like your writing a watchdog for other processes that you did not start, rather than keeping track of child processes.
If a program segfaults, you won't need to kill it. It's dead already.
Use the wait and waitpid calls to wait for children to finish and check the status for some idea of how they exiting. See here for details on how to use these functions. Note especially the WIFSIGNALED and WTERMSIG macros.
waitpid() from SIGCHLD handler to catch the moment when application terminates itself. Note that if you start multiple processes you have to loop on waitpid() with WNOHANG until it returns 0.
kill() with signal 0 to check whether the process is still running. IIRC zombies still qualify as processes thus you have to have proper SIGCHLD handler for that to work.