dtrace: отслеживание всех вызовов функций и распечатка их параметров (пространство пользователя) - PullRequest
3 голосов
/ 23 августа 2011

Я хочу посмотреть, какие функции вызываются в моей программе C99 в пользовательском пространстве и в каком порядке.Кроме того, какие параметры указаны.

Могу ли я сделать это с помощью dtrace?

Например, для программы

int g(int a, int b) { puts("I'm g"); }
int f(int a, int b) { g(5+a,b);g(8+b,a);}
int main() {f(5,2);f(5,3);}

Я вижу текстовый файл с:

main(1,{"./a.out"})
 f(5,2);
  g(10,2);
   puts("I'm g");
  g(10,5);
   puts("I'm g");
 f(5,3);
  g(10,3);
   puts("I'm g");
  g(11,5);
   puts("I'm g");

Я не хочу изменять свой источник, и программа действительно огромна - 9 тысяч функций.

У меня есть все источники;У меня есть программа с отладочной информацией, скомпилированной в нее, и GDB может печатать параметры функции в обратном следе.

Можно ли решить задачу с помощью dtrace?

Моя ОС - одна из BSD, Linux,MacOS, Солярис.Я предпочитаю Linux, но могу использовать любую из перечисленных ОС.

Ответы [ 2 ]

0 голосов
/ 02 мая 2013

Да, вы можете сделать это с помощью dtrace. Но вы, вероятно, никогда не сможете сделать это на Linux. Я пробовал несколько версий Linux-порта dtrace, и он никогда не делал то, что хотел. Фактически, это однажды вызвало панику процессора. Загрузите набор инструментов dtrace с http://www.brendangregg.com/dtrace.html., затем установите соответствующий PATH. Затем выполните это:

 dtruss -a yourprogram args...
0 голосов
/ 24 августа 2011

Ваш вопрос, скорее всего, будет ошибочным. Для любой нетривиальной программы печать последовательности всех вызовов функций, выполняемых с их параметрами, приведет к выводу в несколько МБ или даже в несколько ГБ, что вы не сможете понять (слишком много деталей для человека, чтобы понимать).

Тем не менее, я не верю, что вы можете достичь того, что вы хотите с dtrace.

Вы можете начать с использования флага GCC -finstrument-functions, который позволит вам легко напечатать адреса функций при входе / выходе для каждой функции. Затем вы можете легко преобразовать адреса в имена функций с помощью addr2line. Это дает вам то, что вы просили (кроме параметров).

Если результат не окажется слишком подробным, вы можете установить точку останова для каждой функции в GDB (с помощью команды rb .) и присоединить команду continue к каждой точке останова. Это приведет к тому, что будет достигнут постоянный поток точек останова (с параметрами), но выполнение, вероятно, будет как минимум в 100-1000 раз медленнее.

...