![strace 未找到 shell 函数并出现“Can't stat”错误](https://linux22.com/image/103716/strace%20%E6%9C%AA%E6%89%BE%E5%88%B0%20shell%20%E5%87%BD%E6%95%B0%E5%B9%B6%E5%87%BA%E7%8E%B0%E2%80%9CCan't%20stat%E2%80%9D%E9%94%99%E8%AF%AF.png)
我试图调用一个自定义函数funk_a
,strace
但似乎没有找到它。我确认funk_a可以被自己调用。我很感激任何意见。
$ source ./strace_sample.sh
$ funk_a
Earth, Wind, Fire and Water
$ funk_b
Get on up
strace: Can't stat 'funk_a': No such file or directory
$ dpkg -p strace|grep Vers
Version: 4.8-1ubuntu5
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 14.04.5 LTS
Release: 14.04
Codename: trusty
strace_sample.sh
#!/bin/bash
function funk_a {
echo "Earth, Wind, Fire and Water"
}
function funk_b {
echo "Get on up"
strace -o trace_output.txt -c -Ttt funk_a
}
谢谢。
答案1
strace
只能是strace
可执行文件。
funk_a
是一个函数,是 shell 的编程结构,而不是您可以执行的东西。
唯一strace
可以 strace 的是一个新的 shell,它会评估该函数的主体,例如:
strace -o trace_output.txt -Ttt bash -c "$(typeset -f funk_a); funk_a"
(我删除了,-c
因为它没有意义-Ttt
)。
但是,除了该函数进行的系统调用bash
之外,您还会看到加载和初始化(以及清理和退出之后)所调用的所有系统。write
funk_a
或者你可以strace
在 shell 评估函数时跟踪它的 pid funk_a
:
strace -o trace_output.txt -Ttt -p "$$" &
funk_a
kill "$!"
不过,当附加到 shell 的 PID 时strace
,shell 很可能已经完成了该函数的解释。您可以尝试一些同步,例如
strace -o trace_output.txt -Ttt -p "$$" &
tail -F trace_output.txt | read # wait for some output in trace_output.txt
funk_a
kill "$!"
但即使如此,根据时间安排,trace_output.txt
也会包括一些使用的系统调用解释tail|read
,或者可能会在有时间将命令的跟踪写入输出文件之前kill
终止。strace
echo
更好的方法可能是将调用包装funk_a
在两个可识别的系统调用之间,例如
strace -fo >(sed -n '1,\|open("///dev/null|d
\|open("/dev///null|q;p' > trace_output.txt
) -Ttt -p "$$" &
sleep 1 # give enough time for strace to start
exec 3< ///dev/null # start signal
funk_a
exec 3< /dev///null # end signal
答案2
发现后自己想通了这个线程只能strace
调用可执行文件。
按如下方式更改上面的示例是有效的。
实用工具
#!/bin/bash
echo "Earth, Wind, Fire and Water"
strace_sample.sh
#!/bin/bash
function funk_b {
echo "Get on up"
#strace -o funk_a.out -c -Ttt funk_a
strace -o util.out -c -Ttt ./util.sh
}
结果
$ funk_b
Get on up
Earth, Wind, Fire and Water
$ more util.out
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
0.00 0.000000 0 7 read
0.00 0.000000 0 1 write
0.00 0.000000 0 27 18 open
: