Генерация статического графа вызовов для ядра Linux - PullRequest
16 голосов
/ 27 февраля 2012

Я ищу инструмент для статической генерации графа вызовов ядра Linux (для данной конфигурации ядра). Сгенерированный граф вызовов должен быть «полным» в том смысле, что включены все вызовы, включая потенциальные косвенные, которые, как мы можем предположить, выполняются только с помощью указателей на функции в случае ядра Linux.

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

ncc , кажется, реализует эту идею, однако мне не удалось заставить ее работать на ядре 3.0. Любые другие предложения?

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

В качестве примечания следует отметить, что существуют и другие инструменты, способные выполнять семантический анализ источника для определения потенциальных значений указателей, но, AFAICT, ни один из них не предназначен для использования в проекте, таком как ядро ​​Linux.

Любая помощь будет высоко ценится.

1 Ответ

5 голосов
/ 28 февраля 2012

Мы провели глобальный точечный анализ (с косвенными указателями на функции) и построение полного графа вызовов из монолитных систем C из 26 миллионов строк (18 000 единиц компиляции).

Мы сделали это, используя DMS Software Reengineering Toolkit , его C Front End и соответствующее оборудование для анализа потока .Механизм анализа точек (и другие анализы) является консервативным;да, вы получаете несколько фиктивных точек и, следовательно, вызываете ребра.Это довольно трудно избежать.Вы можете помочь таким анализаторам, предоставив некоторые важные факты о ключевых функциях и используя знания, такие как «встроенные системы [и ОС], как правило, не имеющие циклов в графе вызовов», что означает, что вы можете устранить некоторые из них.Конечно, вы должны учитывать исключения;моя мораль: «в больших системах все происходит».

Особая проблема заключалась в динамически загружаемых (!) модулях C, использующих специальную схему загрузки, специфичную для этого конкретного программного обеспечения, но это только добавило проблемы.*

Приведение к указателям на функции не должно терять ребер;консервативный анализ должен просто предполагать, что указатель приведения соответствует любой функции в системе с сигнатурой, соответствующей приведенному результату.Более проблемными являются отливки, которые производят совместимые подписи;если вы приведете указатель функции к void * foo (uint), когда фактическая вызываемая функция принимает int, точки анализа обязательно будут консервативно выбирать неправильные функции.Вы не можете обвинить анализатор в этом;актерский состав лежит в этом случае.Да, мы видели этот вид мусора в системе из 26 миллионов строк.

Это, безусловно, правильная шкала для анализа Linux (я думаю, что это просто 8 миллионов строк или около того :-).Но мы не пробовали это специально для Linux.

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

...