strace -f на собственной рекурсивной программе на С ++ не будет работать - PullRequest
0 голосов
/ 11 ноября 2018

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

#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

1 Ответ

0 голосов
/ 11 ноября 2018

Нет необходимости использовать mmaps или любые другие системные вызовы, когда fibonacciRec работает.

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

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

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

...