Список всех вызовов функций, сделанных в приложении
Как мы можем перечислить все функции, вызываемые в приложении. Я попытался использовать 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
Запись результатов этой команды с каждой точкой прерывания (заданной при каждом вызове функции) дает аргументы текущей функции.