My understanding is that when we type ls
in the terminal:
- It invokes
fork()
library function which invokes system callclone()
to create a child process. - Then system call
execve()
is invoked to replace address space of the new process created with new content.
In that case I was expecting to see system calls clone()
and execve()
in the strace
ls output. But I am seeing only execve()
and not clone()
.
What could be reason?
I tried the following commands:
strace ls strace -c ls strace -f ls
OS – Redhat
Advertisement
Answer
It’s true, your shell does fork
+ execve
to execute a command, but you are not tracing your shell, so you will not see it!
The strace
tool simply creates a child (through fork
), attaches to it with ptrace
and then does execve
of the requested command, so if you do a simple strace ls
the first thing that you will see is the execve
done by strace
to start ls
.
If you want to see what your shell does, you can start a shell and then attach to it from another shell with strace
.
- Start one shell, then get its PID (in bash just
echo $$
will get you the current shell PID). - Start a second shell, and run
strace -f -p PID_OF_FIRST_SHELL
. - Execute
ls
in the first shell, and whatch the output ofstrace
on the second one.
Note that since strace
traces every syscall by default, and shells are usually very complex programs, you will see a lot of syscalls in the output. If you want to just observe a few syscalls, you can filter them with the -e
option, for example:
strace -e clone,fork,execve -f -p PID_OF_FIRST_SHELL
Example on my machine:
Shell 1:
root@desktop:~/test# echo $$ 30878 root@desktop:~/test# ls -l total 0 -rw-r--r-- 1 root root 0 Oct 15 00:21 a -rw-r--r-- 1 root root 0 Oct 15 00:21 b -rw-r--r-- 1 root root 0 Oct 15 00:21 c -rw-r--r-- 1 root root 0 Oct 15 00:21 d
Shell 2:
root@desktop:~/test# strace -e clone,fork,execve -f -p 30878 strace: Process 30878 attached clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f070ece0a10) = 30958 strace: Process 30958 attached [pid 30958] execve("/bin/ls", ["ls", "--color=auto", "-l"], 0x55c87a5cb9f0 /* 22 vars */) = 0 [pid 30958] +++ exited with 0 +++ --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=30958, si_uid=0, si_status=0, si_utime=0, si_stime=0} --- clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f070ece0a10) = 30959 strace: Process 30959 attached [pid 30959] +++ exited with 0 +++ --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=30959, si_uid=0, si_status=0, si_utime=0, si_stime=0} --- ...