Как я могу проверить, может ли определенная функция косвенно вызываться другой определенной функцией? - PullRequest
1 голос
/ 22 июня 2019

Предполагается, что в проекте, написанном на C, есть функция с именем A и функция с именем B.

Как я могу проверить, может ли функция A находиться в дереве вызовов функции B? Так же, как B-> C-> D-> ...-> A .

Этот вопрос возник, когда я думал о том, какой libvirt API может вызывать qemu qmp "query-block". Поскольку qmp «query-block» вызывается только функцией qemuMonitorJSONQueryBlock. Таким образом, возникает конкретный вопрос: как я могу найти, какой libvirt API может вызвать qemuMonitorJSONQueryBlock?

Я думаю, что на динамический анализ сложно ответить на этот вопрос, потому что требуется много тестов. Это должен быть вопрос статического анализа. Но я мог бы найти подходящие инструменты или методы для ее решения. Наконец, я суммирую вопрос в первом абзаце.

Ответы [ 5 ]

1 голос
/ 24 июня 2019

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

    from m in Methods 
let depth0 = m.DepthOfIsUsedBy("__Globals.B()")
where depth0  >= 0 && m.SimpleName=="A" orderby depth0 
select new { m, depth0 }

enter image description here

0 голосов
/ 26 июня 2019

doxygen может генерировать графики вызовов и графики вызывающих абонентов.Если вы настроите его для неограниченного количества вызовов в графике, вы сможете получить необходимую информацию.

0 голосов
/ 26 июня 2019

Я считаю cscope может помочь решить вопрос.Это инструмент разработчика для просмотра исходного кода .Он может получить функцию вызова следующим образом:
1. Перейдите в каталог исходного кода , затем сгенерируйте файл базы данных cscope с именем cscope.out

cd libvirt
cscope -bR
Найдите вызывающих абонентов из func1 по cscope: cscope -d -f cscope.out -L3 func1, тогда 2-й столбец является вызывающими для этой функции.Например:
cscope -d -f./cscope.out -L3 qemuMigrationDstPrepareDirect

Результат:

src/qemu/qemu_driver.c ATTRIBUTE_NONNULL 12487 ret = qemuMigrationDstPrepareDirect(driver, dconn,
src/qemu/qemu_driver.c qemuDomainMigratePrepare2 12487 ret = qemuMigrationDstPrepareDirect(driver, dconn,
src/qemu/qemu_driver.c qemuDomainMigratePrepare3 12722 ret = qemuMigrationDstPrepareDirect(driver, dconn,
src/qemu/qemu_driver.c qemuDomainMigratePrepare3Params 12809 ret = qemuMigrationDstPrepareDirect(driver, dconn,

Обратите внимание, что: cscope будет ошибочно считать объявление атрибута функции ATTRIBUTE _ * вызывающим.Мы должны их пропустить.

Затем рекурсивно найти вызывающую функцию a.Наконец, выберите цель B -> ...-> A трассировка вызова.

0 голосов
/ 25 июня 2019

Я думаю, что на динамический анализ сложно ответить на этот вопрос, потому что требуется много тестов. Это должен быть вопрос статического анализа. Но я мог бы найти подходящие инструменты или методы для ее решения. Наконец, я суммирую вопрос в первом абзаце.

Это правда, в основном потому, что вы можете вызывать функции, которые вы никогда не связывали в своей программе. с помощью функции dlopen(3) и друзей вы можете динамически связать свою программу с совершенно неизвестной функцией и иметь возможность вызывать ее. Невозможно проверить, действительно ли указатель на функцию хранит действительный указатель, и посмотреть, будет ли он вызываться в результате или нет (или находится ли он в графе вызовов некоторой начальной функции)

0 голосов
/ 24 июня 2019

Вы можете использовать утилиту GNU cflow, которая анализирует коллекцию исходных файлов, написанных на языке программирования C, и выводит зависимости графиков между различными функциями

...