Skip to content
Advertisement

Why am I not able to view the clone() system call in strace output when typing ‘strace ls’ in terminal?

My understanding is that when we type ls in the terminal:

  1. It invokes fork() library function which invokes system call clone() to create a child process.
  2. 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.

  1. Start one shell, then get its PID (in bash just echo $$ will get you the current shell PID).
  2. Start a second shell, and run strace -f -p PID_OF_FIRST_SHELL.
  3. Execute ls in the first shell, and whatch the output of strace 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} ---
    ...
    
User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement