strace -f 在自己的递归 C++ 程序上不起作用
strace -f on own recursive c++ program won't work
所以我有一个简单的递归 C++ 程序,非常基础:
#include <iostream>
int fibonacciRec(int no) {
if (no == 0 || no == 1)
return no;
else
return fibonacciRec(no-1) + fibonacciRec(no-2);
}
int main(int argc, char** argv) {
int no = 42;
for (int i = 1; i <= no; i++) {
std::cout << fibonacciRec(i-1) << " ";
}
std::cout << std::endl;
return 0;
}
现在我要运行strace
在这个程序上,显示所有的系统调用。基本上我想看到很多 mmap 等,但是一旦调用第一个循环,strace -f
就会停止跟随系统调用,只显示最后一个 write
调用。 strace -c
也给出了不太可能的数字,因为程序需要 4-6 秒以上的时间来计算:
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
60.47 0.000078 78 1 munmap
26.36 0.000034 11 3 brk
13.18 0.000017 3 6 fstat
0.00 0.000000 0 4 read
0.00 0.000000 0 1 write
0.00 0.000000 0 5 close
0.00 0.000000 0 14 mmap
0.00 0.000000 0 10 mprotect
0.00 0.000000 0 6 6 access
0.00 0.000000 0 1 execve
0.00 0.000000 0 1 arch_prctl
0.00 0.000000 0 5 openat
------ ----------- ----------- --------- --------- ----------------
100.00 0.000129 57 6 total
当 fibonacciRec
为 运行 时,不需要任何 mmap 或任何其他系统调用。
唯一可能分配的内存是用于递归调用的堆栈内存,有几个原因导致您没有出现在 strace
中:
- 内存确实不多。您的最大递归深度约为 42,并且您只有 1 个局部变量,因此堆栈帧很小。递归期间分配的总堆栈可能少于 1 页。
- 即使内存很大,堆栈分配只会增长,不会缩小,所以您会看到它很快增长到最大值,然后在那里停留很长时间。不会是洪水吧。
- 堆栈分配不是通过系统调用完成的。要向内核请求更多堆栈,您所要做的就是假装您已经拥有它。内核捕获页面错误,注意到错误地址靠近您现有的堆栈,并分配更多。透明到连
strace
都看不到
除了调用自身并返回一个值外,fibonacciRec
除了操作局部变量外什么都不做。没有系统调用。
所以我有一个简单的递归 C++ 程序,非常基础:
#include <iostream>
int fibonacciRec(int no) {
if (no == 0 || no == 1)
return no;
else
return fibonacciRec(no-1) + fibonacciRec(no-2);
}
int main(int argc, char** argv) {
int no = 42;
for (int i = 1; i <= no; i++) {
std::cout << fibonacciRec(i-1) << " ";
}
std::cout << std::endl;
return 0;
}
现在我要运行strace
在这个程序上,显示所有的系统调用。基本上我想看到很多 mmap 等,但是一旦调用第一个循环,strace -f
就会停止跟随系统调用,只显示最后一个 write
调用。 strace -c
也给出了不太可能的数字,因为程序需要 4-6 秒以上的时间来计算:
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
60.47 0.000078 78 1 munmap
26.36 0.000034 11 3 brk
13.18 0.000017 3 6 fstat
0.00 0.000000 0 4 read
0.00 0.000000 0 1 write
0.00 0.000000 0 5 close
0.00 0.000000 0 14 mmap
0.00 0.000000 0 10 mprotect
0.00 0.000000 0 6 6 access
0.00 0.000000 0 1 execve
0.00 0.000000 0 1 arch_prctl
0.00 0.000000 0 5 openat
------ ----------- ----------- --------- --------- ----------------
100.00 0.000129 57 6 total
当 fibonacciRec
为 运行 时,不需要任何 mmap 或任何其他系统调用。
唯一可能分配的内存是用于递归调用的堆栈内存,有几个原因导致您没有出现在 strace
中:
- 内存确实不多。您的最大递归深度约为 42,并且您只有 1 个局部变量,因此堆栈帧很小。递归期间分配的总堆栈可能少于 1 页。
- 即使内存很大,堆栈分配只会增长,不会缩小,所以您会看到它很快增长到最大值,然后在那里停留很长时间。不会是洪水吧。
- 堆栈分配不是通过系统调用完成的。要向内核请求更多堆栈,您所要做的就是假装您已经拥有它。内核捕获页面错误,注意到错误地址靠近您现有的堆栈,并分配更多。透明到连
strace
都看不到
除了调用自身并返回一个值外,fibonacciRec
除了操作局部变量外什么都不做。没有系统调用。