Список всех вызовов функций, сделанных в приложении

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

Мне нужен более подробный список i.e список всех функций, вызываемых основной функцией и вызываемой функцией из этих вызываемых функций и т.д.

Есть ли способ получить это в gdb? Или вы могли бы дать мне предложения о том, как это сделать?

Ответ 1

Как мы можем перечислить все функции, вызываемые в приложении

Для любого приложения с реалистичным размером, этот список будет содержать тысячи записей, что, вероятно, сделает его бесполезным.

Вы можете узнать все функции, определенные (но не обязательно вызываемые) в приложении с помощью команды nm, например.

nm /path/to/a.out | egrep ' [TW] '

Вы также можете использовать GDB для установки точки останова для каждой функции:

(gdb) set logging on     # collect trace in gdb.txt
(gdb) set confirm off    # you wouldn't want to confirm every one of them
(gdb) rbreak .           # set a breakpoint on each function

Как только вы продолжите, вы нажмете точку останова для каждой вызванной функции. Используйте команды disable и continue для перемещения вперед. Я не верю, что есть простой способ автоматизировать это, если вы не хотите использовать скрипты Python.

Уже упомянутый gprof - еще один хороший вариант.

Ответ 2

Вам нужен график вызовов. Инструмент, который вы хотите использовать, - это не gdb, а gprof. Вы скомпилируете свою программу с помощью -pg, а затем запустите ее. Когда он запустит файл gmon.out, будет создан. Затем вы обрабатываете этот файл с помощью gprof и наслаждаетесь выходом.

Ответ 3

запись функции-call-history

https://sourceware.org/gdb/onlinedocs/gdb/Process-Record-and-Replay.html

Это может быть отличная аппаратная ускоренная возможность, если вы один из немногих людей (2015) с процессором, который поддерживает Отслеживание процессоров Intel (Intel PT, intel_pt в /proc/cpuinfo).

Документы GDB утверждают, что они могут создавать выходные данные, например:

(gdb) list 1, 10
1   void foo (void)
2   {
3   }
4
5   void bar (void)
6   {
7     ...
8     foo ();
9     ...
10  }
(gdb) record function-call-history /ilc
1  bar     inst 1,4     at foo.c:6,8
2    foo   inst 5,10    at foo.c:2,3
3  bar     inst 11,13   at foo.c:9,10

Перед его использованием вам нужно запустить:

start
record btrace

где сбой процессора невозможен:

 Target does not support branch tracing.

Поддержка ЦП дополнительно обсуждается в: Как запустить историю записей команд и историю вызовов функций в GDB?

Связанные темы:

Для встроенных вы также рассматриваете JTAG и поддерживающие аппаратные средства, такие как ARM DSTREAM, но поддержка x86 выглядит не очень хорошо: отладка ядра x86 с помощью аппаратного отладчика

Ответ 4

Этот вопрос, возможно, нуждается в разъяснении, чтобы решить, между тем, что в настоящее время является 2 ответами. Зависит от того, что вам нужно:

1) Вам нужно знать, сколько раз каждая функция вызывается в прямом списке/графическом формате функций, соответствующих # вызовам. Это может привести к неоднозначным/неубедительным результатам, если ваш код не является процедурным (т.е. Функции, вызывающие другие функции в структуре ветвления без двусмысленности того, что вызывает то, что). Это базовая функция gprof, которая требует перекомпиляции с флагом -pg.

2) Вам нужен список функций в том порядке, в котором они были вызваны, это зависит от вашей программы, которая является наилучшим/выполнимым вариантом: a) Если ваша программа запускается и завершается без ошибок времени выполнения, вы можете использовать gprof для этой цели. b) Опция ELSE выше с использованием dbg с регистрацией и точками останова - это опция слева, которую я узнал после ее прочтения.

3) Вам нужно знать не только порядок, но, например, аргументы функции для каждого вызова. Моя текущая работа - это моделирование в физике переноса частиц, поэтому это было бы полезно для отслеживания, когда происходят аномальные результаты... т.е. Когда передаваемые аргументы перестают иметь смысл. Я предполагаю, что один из способов сделать это будет вариацией того, что делал русский, кроме использования следующего:

(gdb) info args

Запись результатов этой команды с каждой точкой прерывания (заданной при каждом вызове функции) дает аргументы текущей функции.