Встроенная переменная Dtrace stackdepth всегда возвращает 0 - PullRequest
0 голосов
/ 29 января 2019

Я недавно использую DTrace для анализа моего приложения для iOS。

Все идет хорошо, кроме случаев, когда я пытаюсь использовать встроенную переменную stackDepth。

Я читаю документ здесь, где показано введение встроенной переменной stackDepth.

Поэтому я пишу некоторый D-код

    pid$target:::entry
{
    self->entry_times[probefunc] = timestamp;
}

pid$target:::return 
{
    printf ("-----------------------------------\n");
    this->delta_time = timestamp - self->entry_times[probefunc];
    printf ("%s\n", probefunc);
    printf ("stackDepth %d\n", stackdepth);
    printf ("%d---%d\n", this->delta_time, epid);

    ustack();
    printf ("-----------------------------------\n");
}

И запускаю его с помощью sudo dtrace -s temp.d -c ./simple.out。 Функция unstack () работает очень хорошо, но stackDepth всегда отображается в 0。

Я пробовал как в своем приложении для iOS, так и в простой программе на языке C.

Так что кто-нибудь знает, что происходит?А как получить глубину стека при срабатывании зонда?

Ответы [ 2 ]

0 голосов
/ 12 марта 2019

Вы хотите использовать ustackdepth - глубина стека пользователя-земли.

Переменная stackdepth относится к глубине стека потока ядра;переменная ustackdepth относится к глубине стека потока земли пользователя.Когда отслеживаемая программа выполняется в пользовательской стране, stackdepth всегда будет (должно быть!) Равным 0.

ustackdepth вычисляется с использованием той же логики, которая используется для обхода стека пользовательских земель, как приustack() (так же, как stackdepth и stack() используют аналогичную логику для стека ядра).

0 голосов
/ 31 января 2019

Мне это кажется ошибкой в ​​реализации DTrace для Mac / iOS.

Однако, поскольку вы уже проверяете каждую запись и возврат функции, вы можете просто сохранить новую переменную self->depth ивыполните ++ в датчике :::entry и -- в датчике :::return.Это не работает вполне правильно, если вы запускаете его для оптимизированного кода, потому что любые функции, оптимизированные для хвостового вызова, могут выглядеть так, как будто они входят, но никогда не возвращаются.Чтобы решить эту проблему, вы можете отключить оптимизацию.

Кроме того, поскольку то, что вы делаете, выглядит примерно так, я подумал, что, возможно, вас заинтересует параметр -F:

Объединить вывод трассировки путем определения входа и возврата функции.Отчеты о проверке входа в функцию имеют отступ, и их выводу предшествует ->.Отчеты о проверке возврата функции не имеют отступов, и к их выводу добавляется префикс <-.

Обычный сценарий для использования с -F выглядит примерно так:

pid$target::some_function:entry { self->trace = 1 }

pid$target:::entry /self->trace/ {}
pid$target:::return /self->trace/ {}

pid$target::some_function:return { self->trace = 0 }

Где some_function - это функция, выполнение которой вы хотите распечатать.Вывод показывает текстовый график вызовов для этого выполнения:

-> some_function
  -> another_function
    -> malloc
    <- malloc
  <- another_function
  -> yet_another_function
    -> strcmp
    <- strcmp
    -> malloc
    <- malloc
  <- yet_another_function
<- some_function
...