Иногда мне приходится отслеживать множество вызовов функций, даже для внешних библиотек у меня нет никакого контроля, или я не хочу изменять.
Когда-то я понял, что вы можете комбинировать контрольные точки регулярного выражения gdb (обычные тоже в порядке), а затем просто выполнить набор команд, которые будут запускаться каждый раз при срабатывании этих точек останова. См: http://www.ofb.net/gnu/gdb/gdb_35.html
Например, если вы хотите, чтобы проследить все функции, которые начинаются с префикса «MPI_», вы можете сделать:
(gdb) rbreak MPI_
[...]
(gdb) command 1-XX
(gdb) silent
(gdb) bt 1
(gdb) echo \n\n
(gdb) continue
(gdb) end
Тихая команда используется для скрытия GdB сообщения, когда контрольная точка находится , Обычно я печатаю пару пустых строк, чтобы их было легче читать.
Затем вы просто запустить программу: (GDB) запустить
После того, как ваша программа начнет работать, GDB выведет N верхних уровней трассировки.
#0 0x000000000040dc60 in [email protected]()
#0 PMPI_Initialized (flag=0x7fffffffba78) at ../../src/mpi/init/initialized.c:46
#0 0x000000000040d9b0 in [email protected]()
#0 PMPI_Init_thread (argc=0x7fffffffbe78, argv=0x7fffffffbde0, required=3, provided=0x7fffffffba74) at ../../src/mpi/init/initthread.c:946
#0 0x000000000040e390 in [email protected]()
#0 PMPI_Comm_rank (comm=1140850688, rank=0x7fffffffba7c) at ../../src/mpi/comm/comm_rank.c:53
#0 0x000000000040e050 in [email protected]()
#0 PMPI_Type_create_struct (count=3, array_of_blocklengths=0x7fffffffba90, array_of_displacements=0x7fffffffbab0, array_of_types=0x7fffffffba80, newtype=0x69de20) at ../../src/mpi/datatype/type_create_struct.c:116
#0 0x000000000040e2a0 in [email protected]()
#0 PMPI_Type_commit (datatype=0x69de20) at ../../src/mpi/datatype/type_commit.c:75
Если вы хотите более подробную информацию, печать локальных переменных заданной точки останова также можно просто вставить несколько команд между command
и end
.
Бонусный наконечник: добавьте все это в свой файл .gdbinit
и завершите его выполнение в файл.
Используйте отладчик. Или вызовите в файл какую-либо форму fprintf. Но, возможно, последние варианты не будут хорошими, поскольку вы не хотите изменять исходный код. – Lefteris
Может быть, профилировщик, чтобы получить график вызовов? –
Вы ищете что-то подобное? http://stackoverflow.com/questions/311840/tool-to-trace-local-function-calls-in-linux – delannoyk