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除了操作局部变量外什么都不做。没有系统调用。