slm*_*slm 15 bash debugging strace
受到这个问题的启发,标题为:内置命令何时加载到内存中,在尝试回答这个问题时,我尝试了以下命令,但对我无法运行它感到有点惊讶:
$ strace cd $HOME
Run Code Online (Sandbox Code Playgroud)
有没有一种方法可以用来为 Bash 的内置命令运行 strace?
slm*_*slm 18
如果你考虑一下strace它是如何工作的,那么 Bash 的任何内置函数都是不可追踪的,这是完全合理的。strace只能跟踪实际的可执行文件,而内置程序则不能。
例如,我的cd命令:
$ type cd
cd is a function
cd ()
{
builtin cd "$@";
local result=$?;
__rvm_project_rvmrc;
__rvm_after_cd;
return $result
}
Run Code Online (Sandbox Code Playgroud)
我遇到了这种技术,您可以strace在其中调用实际bash过程,并通过cd这种方式间接跟踪。
$ stty -echo
$ cat | strace bash > /dev/null
Run Code Online (Sandbox Code Playgroud)
这使我能够bash按如下方式跟踪过程:
....
getegid() = 501
getuid() = 500
getgid() = 501
access("/bin/bash", X_OK) = 0
stat("/bin/bash", {st_mode=S_IFREG|0755, st_size=940312, ...}) = 0
geteuid() = 500
getegid() = 501
getuid() = 500
getgid() = 501
access("/bin/bash", R_OK) = 0
getpgrp() = 32438
rt_sigaction(SIGCHLD, {0x43e360, [], SA_RESTORER, 0x34e7233140}, {SIG_DFL, [], SA_RESTORER, 0x34e7233140}, 8) = 0
getrlimit(RLIMIT_NPROC, {rlim_cur=1024, rlim_max=62265}) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8) = 0
fcntl(0, F_GETFL) = 0 (flags O_RDONLY)
fstat(0, {st_mode=S_IFIFO|0600, st_size=0, ...}) = 0
lseek(0, 0, SEEK_CUR) = -1 ESPIPE (Illegal seek)
rt_sigprocmask(SIG_BLOCK, NULL, [], 8) = 0
read(0,
Run Code Online (Sandbox Code Playgroud)
这是 Bash 提示符,它就在那里等待输入。所以让我们给它命令cd ..:
read(0, "c", 1) = 1
read(0, "d", 1) = 1
read(0, " ", 1) = 1
read(0, ".", 1) = 1
read(0, ".", 1) = 1
read(0, "\n", 1) = 1
stat("/home", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat("/home/saml", {st_mode=S_IFDIR|0700, st_size=32768, ...}) = 0
stat("/home/saml/tst", {st_mode=S_IFDIR|0775, st_size=4096, ...}) = 0
stat("/home/saml/tst/90609", {st_mode=S_IFDIR|0775, st_size=4096, ...}) = 0
stat("/home/saml/tst/90609", {st_mode=S_IFDIR|0775, st_size=4096, ...}) = 0
chdir("/home/saml/tst") = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8) = 0
read(0,
Run Code Online (Sandbox Code Playgroud)
从上面的输出中,您可以看到我键入命令的位置,cd ..然后按回车键 ( \n)。从那里你可以看到stat()函数被调用,然后 Bash 坐在另一个read(0..提示符下,等待另一个命令。
到strace外壳做cd /some/dir:
{ strace -p "$$" & sleep 1; cd /some/dir; kill "$!"; }
Run Code Online (Sandbox Code Playgroud)