With timeout
in GNU coreutils
, you can do:
- Get the process id
- Run
timeout 60 strace -p PID
Here is an example.
test.sh
:
#!/bin/bash
while :; do
echo "$$"
sleep 100
done
Run it:
$ ./test.sh
27121
Run strace
with timeout
:
% cuonglm at ~
% timeout 60 strace -p 27121
Process 27121 attached - interrupt to quit
wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 27311
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
--- SIGCHLD (Child exited) @ 0 (0) ---
wait4(-1, 0x7fff374b8598, WNOHANG, NULL) = -1 ECHILD (No child processes)
rt_sigreturn(0xffffffffffffffff) = 0
rt_sigaction(SIGINT, {0x45c4d0, [], SA_RESTORER, 0x7fcdc10e05c0}, {0x443910, [], SA_RESTORER, 0x7fcdc10e05c0}, 8) = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
write(1, "27121\n", 6) = 6
rt_sigprocmask(SIG_BLOCK, [INT CHLD], [], 8) = 0
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7fcdc1a699d0) = 27328
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigaction(SIGINT, {0x443910, [], SA_RESTORER, 0x7fcdc10e05c0}, {0x45c4d0, [], SA_RESTORER, 0x7fcdc10e05c0}, 8) = 0
wait4(-1,
After 1 minute:
....
rt_sigprocmask(SIG_BLOCK, [INT CHLD], [], 8) = 0
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7fcdc1a699d0) = 27328
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigaction(SIGINT, {0x443910, [], SA_RESTORER, 0x7fcdc10e05c0}, {0x45c4d0, [], SA_RESTORER, 0x7fcdc10e05c0}, 8) = 0
wait4(-1, <unfinished ...>
Process 27121 detached
% cuonglm at ~
strace
doesn't run rm -i
for the same reason as:
echo rm
doesn't output rm -i
.
Aliases are a feature of a few shells to allow some strings to automatically be replaced by another when found in command position.
In:
alias foo='whatever'
foo xxx
The shells expands that to:
whatever xxx
and that undergoes another round of interpretation, in that case leading to executing the whatever
command.
aliases are only expanded when found in command position (as the first word of a command line).
zsh
supports global aliases.
You could do:
alias -g rm='rm -i'
But you wouldn't want to, as that would mean that:
echo rm
would output rm -i
for instance.
Best Answer
A process can spend any amount of time not doing any system call.
For instance a shell doing a
while :; do :; done
will spend an infinite amount of time not doing any system call and not spending anysys
CPU time, onlyuser
CPU time.strace -c
tries to count thesys
CPU time by each system call. Ananosleep(1000000000)
will spend close to 0ms CPU time but 1s wall clock time.Comparing the sys time with the time reported by strace would make more sense but note that not all sys CPU time accounted to the process is spent in those syscalls. Accessing mmaped data for instance can make the process spend a lot of system time without doing any system call.
Here, those numerous
mmaps()
calls could be to allocate memory. Those are instantaneous, as they just update some mappings. But the first time you write to those, that's where some system time is needed to back those writes with actual memory.Or they could be to map object files like shared libraries (that's also a likely possibility as the number is not far from the number of
open()s
). Then again, themmap()
is quick, but reading the memory later does also mean some page faults and actual time to read the data off disk, which is not accounted to any system call.More fundamentally, if you do
time strace -f your-application
as in an earlier version of your question,time
will time both the command andstrace
.strace
adds a lot of overhead. It does itself a few system calls for each system call of the straced application.Doing
instead of
is more likely to give you a better match.
What I find though is that for the
wait*()
system calls that processes make to wait their children,strace
counts the time reported by thosewait*()
system calls as system time, which means that the time of the children processes (at least the ones that are waited for) is counted several times. That matters instrace -f time cmd
astime
does runcmd
in a child process and waits for it.time
andstrace
report the same sys time (as returned by thewait4()
system call), but with-f
:The 1.33 is the time reported by the one
wait4()
system call thattime
does. That reports the sys time ofhead
(time
's child).However,
strace
also tries to get the system time for every syscall of itshead
grandchild on top of that, which means that is counted twice (not exactly). That stracing of the grand child does still incur some overhead accounted to the straced process as we get 1.33 as opposed to 0.76 earlier. That is considerably reduced if I force strace, time and head to run on the same processor (withtaskset 1
).