如何解决在终端中键入“ strace ls”时,为什么我无法在strace输出中查看clone系统调用?
我的理解是,当我们在终端中输入ls
时:
- 它调用
fork()
库函数,后者调用系统调用clone()
创建一个子进程。 - 然后调用系统调用
execve()
,以用新内容替换新创建的新进程的地址空间。
在那种情况下,我期望在clone()
ls输出中看到系统调用execve()
和strace
。但是我只看到execve()
而不是clone()
。
可能是什么原因?
我尝试了以下命令:
strace ls
strace -c ls
strace -f ls
OS-Redhat
解决方法
是的,您的外壳程序执行fork
+ execve
来执行命令,但是您没有在跟踪外壳程序,因此您将看不到它!
strace
工具仅创建一个子项(通过fork
),并用ptrace
附加到该子项,然后执行所请求命令的execve
,因此如果执行简单的strace ls
首先,您将看到execve
完成的strace
以启动ls
。
如果要查看您的shell的功能,可以启动一个shell,然后使用strace
从另一个shell附加到它。
- 启动一个shell,然后获取其PID(在bash中,
echo $$
会为您提供当前的shell PID)。 - 启动第二个shell,然后运行
strace -f -p PID_OF_FIRST_SHELL
。 - 在第一个外壳中执行
ls
,然后在第二个外壳中获取strace
的输出。
请注意,由于strace
默认情况下会跟踪每个syscall,并且shell通常是非常复杂的程序,因此您会在输出中看到很多syscall。如果您只想观察几个系统调用,则可以使用-e
选项对其进行过滤,例如:
strace -e clone,fork,execve -f -p PID_OF_FIRST_SHELL
我的机器上的示例:
-
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,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,child_tidptr=0x7f070ece0a10) = 30959 strace: Process 30959 attached [pid 30959] +++ exited with 0 +++ --- SIGCHLD {si_signo=SIGCHLD,si_pid=30959,si_stime=0} --- ...
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。