linux — strace -f на собственной рекурсивной программе на С ++ не будет работать

поэтому у меня есть простая рекурсивная программа на С ++, очень простая:

#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 на этой программе, показывая все системные вызовы. В основном я хочу видеть много mmaps и т. Д., Но как только вызывается первый цикл, 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

0

Решение

Там нет необходимости каких-либо карт или любых других системных вызовов, когда fibonacciRec бежит.

Единственная память, которая может быть выделена, это стековая память для рекурсивных вызовов, и есть несколько причин, по которым вы не видите их в strace:

  • Это действительно не много памяти. Ваша максимальная глубина рекурсии составляет около 42, и у вас есть только 1 локальная переменная, поэтому кадры стека малы. Общий стек, выделенный во время рекурсии, вероятно, составляет менее 1 страницы.
  • Даже если бы памяти было много, выделение стека только увеличивается, оно никогда не уменьшается, поэтому вы увидите, что оно довольно быстро вырастет до максимума, а затем останетесь там надолго. Это не было бы потопом.
  • Распределение стека в любом случае не выполняется системным вызовом. Чтобы запросить у ядра больше стека, все, что вам нужно сделать, это притвориться, что оно у вас уже есть. Ядро улавливает ошибку страницы, замечает, что ошибочный адрес находится рядом с вашим существующим стеком, и выделяет больше. Это настолько прозрачно, что даже strace не могу видеть это.

Помимо вызова себя и возврата значения, fibonacciRec ничего не делает, но манипулирует локальными переменными. Системных звонков нет.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]