I need to track the process status ps axf during executable lifetime.
Let's say I have executable main.exec and want to store into a file all subprocess which are called during main.exec execution.
$ main.exec &
$ echo $! # and redirect every ps change for PID $! in a file.
strace - trace system calls and signals
$ main.exec &
$ strace -f -p $! -o child.txt
-f Trace child processes as they are created by currently traced processes as a result of the fork(2), vfork(2) and clone(2) system calls. Note that -p PID -f will attach all threads of process PID if it is multi-threaded, not only thread with thread_id = PID.
If you can't recompile and instrument main.exec, ps in a loop is a simple option that may work for you:
while true; do ps --ppid=<pid> --pid=<pid> -o pid,ppid,%cpu,... >> mytrace.txt; sleep 0.2; done
Then parse the output accordingly.
top may also work, and can run in batch mode but not sure if you can get it to dynamically monitor child processes like ps. Don't think so.
Related
I am trying to see what would happen about system call when I running one command, but it seems those command after | can't be shown? like:
strace -f cat a.txt| cat
It seems strace and -f perimeter can show the whole process. I think the last part is in the child progress created by fork. Why and how to make it?
From the strace manual (emphasis mine).
-f Trace child processes as they are created by
currently traced processes as a result of the fork(2),
vfork(2) and clone(2) system calls.
The traced process in your case is the first cat process. The second cat process is not a child of the first cat process. The fork is done by the shell.
One way to achieve what you want is to trace the shell:
strace -f bash -c "cat a.txt| cat"
I was trying to get pid of process I ran with setsid and which ought to run in background like this:
test.sh:
#/bin/bash
setsid nohup ./my_program &
echo $!
if I run ./test.sh it will print a pid of my_program process and it's exactly what I need. But if run this commands one by one in my shell like this:
$ setsid nohup ./my_program &
$ echo $!
It will give me a pid of setsid command (or may be something else, but it almost all times gives me pid of my_program minus one).
What is happening here? Why results of commands I ran in terminal by myself differs from results of test.sh script?
Btw, may be you know some easy way of process which I started with setsid and which I need to run in background?
Repost of comments above as an answer:
This is because setsid only forks the current process if it is the process group leader. A detailed explanation can be found here.
To get the pid of a process executed via setsid, the approaches given here may be tried.
setsid will call fork to ensure that it creates a new process group aswell as a new session, hence the resulting pid will not match the pid of setsid. The most clean work-around would be that my_program stores its pid into a file.
When you later want to send kill to my_program, you should check that the pid actually matches a program named my_program via /proc file system or calling the ps command with some magic code around it. (This is a very common method used by many daemons)
I want to monitor all the running processes using strace and when a process ends the output of the strace should be sent to a file.
And how to find every running proc PID. I also want to include process name in the output file.
$ sudo strace -p 1725 -o firefox_trace.txt
$ tail -f firefox_trace.txt
1725 would be the PID of the proccess you want to monitor (you can find the PID with "ps -C firefox-bin", for firefox in the example)
And firefox_trace.txt would be the output file !
The way to got would be to find every running proc PID, and use the command to write them in the output file !
Considering the doc,
-p pid
Attach to the process with the process ID pid and begin tracing. The
trace may be terminated at any time by a keyboard interrupt signal (
CTRL -C). strace will respond by detaching itself from the traced
process(es) leaving it (them) to continue running. Multiple -p options
can be used to attach to up to 32 processes in addition to command
(which is optional if at least one -p option is given).
Use -o to store the output to the file, or 2>&1 to redirect standard error to output, so you can filter it (grep) or redirect it into file (> file).
To monitor process without knowing its PID, but name, you can use pgrep command, e.g.
strace -p $(pgrep command) -o file.out
where command is your name of process (e.g. php, Chrome, etc.).
To learn more about parameters, check man strace.
I have a bash process which calls another child process (mysqldump) for example. I need to determine the io usage of this child process. I tried cat /proc/self/io but values for io are connected only with the parent process. But I need the data for the child process. I can determine the pid of the child process and try view /proc/[pid of child]/io but when should I do that? If I do mysqldump and then /proc/[pid of child]/ioŠ± /proc/[pid of child] won't exist after the finishing of the child process. Thanks!
You can probably use strace command as below to get that result.
strace -e trace=read,write -o ls.log ls
Here, strace will give the result for ls command. If you want to attach to particular process, use the -p pid option like
strace -e trace=read,write -o ls.log -p <child process PID>
More about Strace Command Here
How to run a program and know its PID in Linux?
If I have several shells running each other, will they all have separate PIDs?
Greg's wiki to the rescue:
$! is the PID of the last backgrounded process.
kill -0 $PID checks whether $PID is still running. Only use this for processes started by the current process or its descendants, otherwise the PID could have been recycled.
wait waits for all children to exit before continuing.
Actually, just read the link - It's all there (and more).
$$ is the PID of the current shell.
And yes, each shell will have its own PID (unless it's some homebrewed shell which doesn't fork to create a "new" shell).
1) There is a variable for that, often $$:
edd#max:~$ echo $$ # shell itself
20559
edd#max:~$ bash -c 'echo $$' # new shell with different PID
19284
edd#max:~$ bash -c 'echo $$' # dito
19382
edd#max:~$
2) Yes they do, the OS / kernel does that for you.
the top command in linux(Ubuntu) shows the memory usage of all running programs in linux with their pid. Kill pid can kill the process.