Linux check process alive

check is Process is Alive from PID while handling recycled PID

From what I seen online you call kill method in c++ in order to see if the process is alive. the issue with that is PID’s get rycled and the same PID your looking for may not be the same process. I have a program that has two processes that are not children of each other. The only way to communicate with them is IPC. I would like my host process to shutdown when the client process shuts down. In order to do that I have to know when the client’s process is no longer alive. In Windows, they have what’s called a process handler that will reserve the PID from getting recycled until the process that created the handle is closed. I am wondering how to achieve this for macOS/Linux (POSIX) systems. The problematic code as PID’s are reycled.

I’m not a programmer, so the other advice is probably better, but I latched onto this statement: «The only way to communicate with them is IPC». Would it be reasonable to set up some kind of heartbeat protocol between the two endpoints? When the other side stops heartbeating, you know you’ve lost that process.

@JeffSchaller issue is solved already. IPC heartbeat would DC occasionally and return false positives I don’t want this. This is why we check for PIDisAlive. I fixed it in my answer below using the process start time along with the PID.

2 Answers 2

From what I seen online you call kill method in c++ in order to see if the process is alive. the issue with that is PID’s get rycled and the same PID your looking for may not be the same process

Exactly, so that kill approach does not work. Really, end of story there. It’s not a working tool for this.

  • if the process you’re watching is your child process (or in your own process’ process group), waitpid is meant exactly for watching when it exits
  • if the process is not your child process, POSIX «ideals» kind of suggest your own process has no business interacting tightly with that process’ lifetime (at least that’s my takeawy from waitpid ‘s limitations). You can hope that you have «tracing» privileges and use ptrace to attach to the other process and wait for exit calls.
Читайте также:  Epson l132 drivers linux

this isn’t an answer. I specifically stated that it’s not a child process. this is because a server has no business spawning a client and it communicates via IPC. I would like to how to check if the client is alive from server. and if the server is alive from client

ptrace causes more issues then it solves. It requires your process to handle tracing and I wanted a generic is process alive without that crap. It also pauses the client and there isn’t a way to stop that once the trace has been setup. I need a way to reserve the PID while my PID checker is running

Don’t know why you are so negative. I explain why there’s no simple solution, and oder you a workable alternative.

there actually was a huge easy fix for this don’t know why everyone is stating there is no solution. the solution is to check the process’s creation time when checking if PID isAlive on top of checking if it was alive. this will now prevent PID conflicts from returning true instead of false

The solution is to either reserve the PID on windows by cacheing and not closing the process handle . For POSIX Systems we simply get the process’s start time from the kernal OS DEPENDANT! and then check if the cached start time equals the current start time. If it doesn’t a PID conflict is detected and it returns false.

#include #include #include #include map handles; bool isProcessAlive(DWORD pid) < HANDLE process; if(handles.find(pid) == handles.end()) < process = OpenProcess(SYNCHRONIZE, FALSE, pid); handles[pid] = process; >else < process = handles[pid]; >DWORD ret = WaitForSingleObject(process, 0); bool isRunning = ret == WAIT_TIMEOUT; if(!isRunning)//close the cached handle to free the PID and erase from the cache < CloseHandle(process); handles.erase(pid); >return isRunning; > 
#include #include #include #include #include #include #include #include #include #include /** * map of unsigned long, creation time either in jiffies, ms, or in clock ticks or different on mac even. so we keep it as a string */ std::map handles; /** * returns true if the process is alive and attempts to suggest a handle to linux's os that we are reading the directory /proc/[PID] reserve this PID till program shutdown */ bool isProcessAlive(unsigned long pid) < // Get process info from kernel struct kinfo_proc info; int mib[] = < CTL_KERN, KERN_PROC, KERN_PROC_PID, (int)pid >; size_t len = sizeof info; memset(&info,0,len); int rc = sysctl(mib, (sizeof(mib)/sizeof(int)), &info, &len, NULL, 0); //exit program sysctl failed to verify PID if (rc != 0) < handles.erase(pid); return false; >//extract start time and confirm PID start time equals org start time struct timeval tv = info.kp_proc.p_starttime; if(tv.tv_sec == 0) < handles.erase(pid); return false; >string time = to_string(tv.tv_usec) + "-" + to_string(tv.tv_sec); if(handles.find(pid) != handles.end()) < string org_time = handles[pid]; if(org_time != time) < cout > else < handles[pid] = time; >return true; > 
#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "/usr/include/x86_64-linux-gnu/sys/param.h" /** * map of unsigned long, creation time either in jiffies, ms, or in clock ticks or different on mac even. so we keep it as a string */ std::map handles = <>; /** * returns true if the process is alive and attempts to suggest a handle to linux's os that we are reading the directory /proc/[PID] reserve this PID till program shutdown */ bool isProcessAlive(unsigned long pid) < ifstream procFile; string f = "/proc/"+ std::to_string(pid)+ "/stat"; procFile.open(f.c_str()); if(!procFile.fail()) < //get creation time of current pid's process char str[255]; procFile.getline(str, 255); // delim defaults to '\n' vectortmp; istringstream iss(str); copy(istream_iterator(iss), istream_iterator(), back_inserter (tmp)); string creation_time = tmp.at(21); //check if the process's creation time matches the cached creation time if(handles.find(pid) != handles.end()) < string org = handles[pid]; //if the pid's creation time is not the cached creation time we assume it's not the same process and the original has closed //unlike java the ==,!= actually checks .equals() when comparing if(creation_time != org) < std::cerr > handles[pid] = creation_time; procFile.close(); return true; > handles.erase(pid); procFile.close(); return false; > 

Источник

linux kernel check if process is still running

I’m working in kernel space and I want to find out when an application has stopped or crashed. When I receive an ioctl call, I can get the struct task_struct where I have a lot of information regarding the process of the application. My problem is that I want to periodically check if the process is still alive or better yet, to have some asynchronous call when the process is killed. My test environment was on QEMU and after a while in the application I’ve run a system(«kill -9 pid«). Meanwhile in the kernel I’ve had a periodical check on task_struct with:
volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */
static inline int pid_alive(struct task_struct *p)
The problem is that my task_struct pointer seems to be unmodified. Normally I would say that each process has a task_struct and of course it is corespondent with the process state. Otherwise I don’t see the point of «volatile long state» What am I missing? Is it that I’m testing on QEMU, it is that I’ve tested checking the task_struct in a while(1) with an msleep of 100? Any help would be appreciated. I would be partially happy if I could receive the pid of the application when the app is closing the file descriptor of the module («/dev/driver»). Thanks!

3 Answers 3

You cannot hive off the task_struct pointer and refer to it later. If the process has been killed, the pointer is no longer valid — that task_struct is gone. You also should not be using PID values within the kernel to refer to processes. PID values are re-used, so you might not even be talking about the same process.

Your driver can supply a .release callback, which will be called when your driver file is closed, including if the process is terminated or killed. You can access current from this callback. Note that if a process opens your file and then forks, the process calling .release could well be different from the process that called .open . Your driver must be able to handle this.

It has been a long time since I mucked around inside the kernel. It seems to me if your process actually dies, then your best bet would be to put hooks into the code that tears down processes. If it doesn’t die but gets caught in a non-responsive loop, you’d probably be better off causing an application level core dump.

A solution that worked beautifully in my operating systems homework is to use a kprobe to detect when do_exit is called. What’s beautiful is that do_exit will always be called, no matter how the process is closed. I think even in the case of a kernel oops this one will still be called.

You should also hook into _do_fork , just in case.

Oh, and look at the .release callback mentioned in the other answer (do note that dup2 and fork will cause unexpected behavior — you will only be notified when the last of the copies created by these two is closed).

Hot Network Questions

Subscribe to RSS

To subscribe to this RSS feed, copy and paste this URL into your RSS reader.

Site design / logo © 2023 Stack Exchange Inc; user contributions licensed under CC BY-SA . rev 2023.7.17.43536

By clicking “Accept all cookies”, you agree Stack Exchange can store cookies on your device and disclose information in accordance with our Cookie Policy.

Источник

Оцените статью
Adblock
detector