5

This question is relevant to the question of 'what happens when we type a simple command on shell?' I posted earlier. (I thought it would be better to post it separately. But if not, please let me know.)

I learned from the previous question that the shell built-in commands are treated specially and normal external commands are executed on child process.

This time, I would like to trace system calls such as fork, clone, or execve to monitor what really happened after typing command. But I can only trace an execve call execve("bin/ls",,,) = 0 when I execute strace like this way.

strace -etrace=execve,clone ls

That means, as I guess, I can only monitor system calls which are called after a child process is created.

To monitor all system calls related to creating new process, What I have to do? To invoke command with bash -c like strace -etrace=execve,clone bash -c '{ ls; }' would be helpful in this case?

  • @ThomasNyman Yes, my question seems to be dupulicate of the question you menentioned. I will read the answers carefully. Thanks – MS.Kim Apr 7 '14 at 5:53
  • You need to add the -f (or -ff) option to strace for it the follow children. strace -f -etrace=execve,clone bash -c '{ ls; }' should do what you are looking for. – Graeme Apr 7 '14 at 10:16
  • This should never have been closed as duplicate of the question it was - it is clearly about using strace to follow children rather than following shell builtins. – Graeme Apr 7 '14 at 10:22
4

As mentioned in one of the answers to your previous question, the exec family call happens after the child process is created, so if you want it to appear in the strace output then you have to make it also follow children of the shell process you are tracing.

You can do this by adding either the -f or -ff options, here are the relevant man page snippets:

 -f  Trace child processes as they are created by currently traced processes as a
     result of the fork(2) system call.
-ff  If the -o filename option is in effect, each processes trace is written to
     filename.pid where pid is the numeric process id of each process.  This is
     incompatible with -c, since no per-process counts are kept.

To trace the relevant calls involved in running a command in bash you can do:

strace -f -e trace=process bash -c 'ls; :'

The -e trace=process specifically traces all calls involved in process management. Also the second no-op command (:) is needed as if you run bash with only a single command, it is smart enough to just do an execve without forking since it knows it doesn't need to do anything else.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.