cod*_*ver 1 linux ls system-calls linux-kernel strace
我的理解是,当我们ls在终端输入:
fork()库函数,库函数调用系统调用clone()
来创建子进程。execve()调用以用新内容替换创建的新进程的地址空间。在这种情况下,我希望在ls 输出clone()中看到系统调用。但我只看到而不看到。execve()straceexecve()clone()
可能是什么原因?
我尝试了以下命令:
strace ls
strace -c ls
strace -f ls
Run Code Online (Sandbox Code Playgroud)
操作系统-红帽
确实,您的 shell 使用fork+execve来执行命令,但您没有跟踪您的 shell,因此您不会看到它!
该strace工具只是创建一个子级(通过fork),使用所请求的命令附加到它ptrace,然后执行execve请求的命令,因此,如果您执行简单的操作,strace ls您将看到的第一件事就是startexecve完成的操作。stracels
如果您想查看shell 的功能,可以启动一个 shell,然后使用 附加到另一个 shell strace。
echo $$获取当前 shell PID)。strace -f -p PID_OF_FIRST_SHELL.ls执行输出。strace请注意,由于strace默认情况下会跟踪每个系统调用,并且 shell 通常是非常复杂的程序,因此您将在输出中看到很多系统调用。如果您只想观察一些系统调用,可以使用以下-e选项过滤它们,例如:
strace -e clone,fork,execve -f -p PID_OF_FIRST_SHELL
Run Code Online (Sandbox Code Playgroud)
我的机器上的示例:
外壳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
Run Code Online (Sandbox Code Playgroud)
外壳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} ---
...
Run Code Online (Sandbox Code Playgroud)