Record child processes in Linux - linux

I'm looking for a way to record child processes and their arguments spawned by a script or other command. A good example would be recording the build commands spawned by "make" and any children they, in turn, spawn.
In my specific case working with a build script from an embedded systems manufacturer. It's a Python script that calls cmake, ninja, and heaven knows what else. I'd really like to know what's being called so I can maybe pare down the noise.
This seems like an obvious utility for someone to have written decades ago but I'll be darned if I can find it.
Much thanks for any advice.

Related

execv() the exact same binary on Linux?

I am looking for a way on Linux to fork a child process that runs exactly the same binary as its parent.
The basic mechanism that I see available is fork() and execv(). The trouble is what parameter to supply to execv() to run exactly the same code?
The nearest solution I have found is to run /proc/$$/exe. The trouble is that this is only a symlink and so if the executable had been modified on disk after my process started then the child would end up running the new version. I am looking for a more robust solution such that in practice I can depend on the parent and child processes to be running the same code even if software is being reinstalled in the background.

list of all executions in Linux

Is it possible to find out all the programs getting executed in Linux. There will be many scripts and other executables getting launched and killed during the life time of a system and I would like to get a list of these (or a print while execuction start). I am looking for this to understand program flow in an embedded board.
Type ps aux in the terminal will give information about the processes(Started time, runtime), more information about keep track of processes
There's a kernel interface which will notify a client program of every fork, exec, and exit. See this answer: https://stackoverflow.com/a/8255487/5844347
Take a look at ps -e and eventually crontab if you want to take that information periodically.

is it possible to run multiple executables in a shell script with the same PID?

I have a simple Shell script in which multiple executables will run sequentially. Every time a new executable starts to run, a new process with a new PID will start. Is it possible to run them with the same PID? I know for a shell script, we can use "source". But I do not know how to handle executables.
In principle, I believe it should be possible, but in practice it would be very complicated and brittle.
The exec family of system calls in Linux allows a process to replace itself with an entirely new process, which holds on to the same PID. The tricky part would be to somehow "return" from the second process back to the first. When exec is called, the OS loads everything it needs to start running the new process, and wipes out every piece of state related to the current process (the one being replaced). And when the new process terminates, the OS releases all resources (including the PID) associated with that process.
So if you really wanted to do this, you would have to hijack how processes terminate in order to restart your original process rather than let the OS clean everything up. How can you do this? Well, execle and execvpe functions allow a program to specify the environment of the new process before starting the process. Since every process depends on libc (or equivalent) to bring up/tear down a process, you should be able to provide a custom libc which would re-start execution of your script, or exec another process. The great difficulty would be hacking such a libc. Additionally, you would have to figure out a good way for your master program to keep state even though the OS wipes away any memory it might have been using when it called exec. You can probably accomplish this with temporary files.
So long story short, don't do it. While it's kind of fun for me to sit here and think about the massive hacks that would be required to pull this off, it would be a huge pain and I'm sure there is a much more elegant solution to whatever problem you are actually trying to solve.
The PID is assigned by OS when shell creates a new process. There is no way to tell the OS to use some specific PID. So it's not possible.

linux - check if program has died

i wrote a program that needs to continuously run. but since im a bad programmer it crashes every so often. is there a way to have another program watch it and restart it when it crashes?
Not to be specious, but if you're a bad programmer, what's to say your watching programming won't fail too ;) And, you should get better so that you don't have this issue (for this reason). That said, you will probably have need of the following answer eventually.
However, if getting better isn't possible, just run a cron job at regular intervals looking for the name of your program in the output from 'ps'. And that answer you can get from superuser.com
No need for 3rd party programs
All of this can be accomplished with the linux inittab
inittab MAN pages
Look for "respawn"
You can use supervisord
http://supervisord.org/
Since Stackoverflow is a programming site, let me give you an overview of how such a watcher would be implemented.
First thing to know is that your watcher will have to start the watched program yourself. You do this with fork and exec.
What you can then do is wait for the program to exit. You can use of the wait system calls (i.e. wait, waitpid or wait4) depending on your specific needs. You can also catch SIGCHLD so that you can get asynchronously informed when your child exits (you will then need to call wait to get it's status).
Now that you have the status, you can tell if the process died due to a signal with the macro WIFSIGNALED. If that macro returns true, then your program crashed and needs to be restarted.
It still won't continuously run if you have another task monitoring it... it will still have a short amount of down time while it restarts.
Additionally, if you are acting as a network (or local) server process, you'll lose any state about requests in progress; I hope this is ok (Of course your clients may have built-in timeout and retry).
Finally, if your process crashed while it was in the middle of storing any persistent data, I hope it has a mechanism of coping with half-written files, etc.
However, if you intend it to be robust, all of these things should be true anyway, so you can use something like supervisord safely.
I use Monit to watch over my programs and services.

How do I reliably track child/grandchild processes on a POSIX system?

I have an interesting (at least to me) problem: I can't manage to find a way to reliably and portably get information on grandchildren processes in certain cases. I have an application, AllTray, that I am trying to get to work in certain strange cases where its subprocess spawns a child and then dies. AllTray's job is essentially to dock an application to the task tray, which is (usually) specified as a command line for AllTray to invoke (i.e., alltray xterm would start xterm, and manage it in AllTray).
Most GUI software runs just fine under it. It sets the _NET_WM_PID property on its window (or a widget library does) and all's well, because _NET_WM_PID == fork()ed child. However, in some cases (such as when running oowriter, or software written to run under KDE such as K3b), the child process that AllTray runs is a wrapper, be it a shell script (as in OO.o's case) or a strange program that fork()s and exec()s itself and effectively backgrounds itself, since the parent process dies very early.
I had the idea to not reap my child processes, so as to preserve in the process table the parent process ID for my grandchildren, so that I could link them back to me by traversing the family tree from bottom-to-top. That doesn't work, though: once my child process dies and turns into a zombie, the system considers my grandchild process to be an orphan, and init adopts it. This appears to be the case on at least Linux 2.6 and NetBSD; I'd presume it's probably the norm, and POSIX doesn't seem to specify that to be the case, so I was hoping for the opposite.
Since that approach won't work, I thought about using LD_PRELOAD and intercepting my child process' call to fork(), and passing information back to my parent process. However, I'm concerned that won't be as portable as the ideal solution, because different systems have different rules on how the dynamic linker does things like LD_PRELOAD. It won't work for setuid/setgid GUI applications either without the helper library also being setuid or setgid, at least on Linux systems. Generally, it smells like a bad idea to me, and feels quite hackish.
So, I'm hoping that someone has an idea on how to do this, or if the idea of relying on a mechanism like LD_PRELOAD is really the only option I have short of patching kernels (which is not going to happen).
You could investigate the possibility of using process groups to keep track of, well, process groups. A process group is a property (just a number) which you can set before forking, and child processes then inherit it automatically.
AllTray can create a new process group for each application started with it. You can the send signals to all members of the process group. I suppose the most useful signals here would be TERM and KILL, in order to kill an application managed in AllTray.
I'm not sure if there is a convenient way to figure out if all members of the process group have already exited or not. You may have to resort to going through the entire process list and call getpgid for each process to see if there are any left in the process group.
Note that process groups won't work for applications which create new process groups themselves. But that's relatively rare and you probably don't need to worry about such applications.

Resources