Сделать GDB управление потоком печати функций, так как они называются
Как сделать интересные функции печати gdb, так как они называются, отступом в зависимости от того, насколько глубоко они находятся в стеке?
Я хочу сказать что-то вроде (составленное):
(gdb) trace Foo* Bar* printf
И gdb напечатайте все функции, которые начинаются с Foo или Bar, как они называются. Вид вроде gnu cflow, за исключением использования отладочных символов и только функций печати, которые фактически вызываются, а не все возможные потоки вызовов.
Инструменты, которые не помогут включить cachegrind, callgrind и oprofile, которые упорядочивают результаты, с помощью которых функции вызывались чаще всего. Мне нужен порядок вызова.
Подстановочный знак (или эквивалент) необходим, так как существует много функций Foo и Bar. Хотя я бы согласился на запись абсолютно каждой функции. Или, возможно, указывая gdb на запись всех функций в определенной библиотеке.
Некоторые мастера GDB должны иметь script для этого общего задания!
Ответы
Ответ 1
В вашем случае я перейду к команде define
в gdb, что позволит вам определить функцию, которая может принимать до 10 аргументов.
Вы можете передавать имена функций для "трассировки" в качестве аргументов для функции, которую вы определяете, или записывать их все в самой функции. Я бы сделал что-то вроде следующего
define functiontrace
if $arg0
break $arg0
commands
where
continue
end
end
if $arg1
...
Аргументы к определяемой пользователем функции в gdb называются $arg0- $arg9. Кроме того, вы можете просто записать каждую функцию, которую вы хотите отслеживать в функции, вместо использования $arg0-9.
Примечание. Это не будет иметь отступ по глубине в трассировке стека, но будет печатать трассировку стека при каждом вызове функции. Я считаю этот подход более полезным, чем strace и т.д., Потому что он будет регистрировать любую функцию, которую вы хотите, систему, библиотеку, локальную или другую.
Ответ 2
Использовать правильный инструмент для задания;)
Как напечатать следующие N выполненных строк автоматически в GDB?
Ответ 3
Там rbreak
cmd принимает регулярное выражение для установки контрольных точек. Вы можете использовать:
(gdb) rbreak Foo.*
(gdb) rbreak Bar.*
(gdb) break printf
Подробные сведения о контрольных точках см. в этом.
Затем используйте commands
для печати каждой функции по ее вызову. Например. пусть α = номер последней точки останова (вы можете проверить ее с помощью i br
, если вы пропустили), а затем выполните:
(gdb) commands 1-α
Type commands for breakpoint(s) 1-α, one per line.
End with a line saying just "end".
>silent
>bt 1
>c
>end
(gdb)
Некоторая разработка: silent
подавляет ненужные информационные сообщения, bt 1
печатает последний кадр backtrace (т.е. текущую функцию), c
является ярлыком для continue
, для продолжения исполнения и end
это просто разделитель списка команд.
NB: если вы трассируете библиотечные функции, вам может потребоваться ожидание загрузки lib. Например. установите разрыв на main
или любую другую функцию, запустите приложение до этой точки и только затем установите точки останова, которые вы хотели.
Ответ 4
Вы видели яркую отличную ссылку на аналогичную запись здесь?
Он использует readelf для получения интересных символов, команд gdb для получения трассировки и awk для склеивания всего этого.
В основном вам нужно изменить его команду gdb script, чтобы удалить 1 глубину из backtrace, чтобы увидеть стек и фильтровать определенные функции, и переформатировать вывод с помощью awk/python/(...) script, чтобы представить его как дерево. (Я признаю, что я слишком ленив, чтобы сделать это сейчас...)
Ответ 5
Вы можете вызвать gdb
в пакетном режиме (с использованием опции -x
), сломать, где вам нужно, и запросить обратную трассировку (bt
), затем вы фильтруете результат с помощью grep
или egrep
.
Отступы сложнее, однако вывод bt
упорядочен, поэтому у вас есть текущая функция в верхней части трассы и main
в самом низу.
Итак, вы создаете файл с командами:
br <function name where to break>
run
bt
kill
quit
затем запустите gdb <program> -x<command file>
Фильтровать строки, начинающиеся с #<digit>
- вы получаете трассировку стека.