Введение

Структура в вычислительной технике

Граф вызовов (также известный как мультиграф вызовов) — это граф потока управления, представляющий отношения вызовов между подпрограммами в компьютерной программе. Каждый узел соответствует процедуре, а каждое ребро (f, g) указывает, что процедура f вызывает процедуру g. Следовательно, цикл в графе свидетельствует о рекурсивных вызовах процедур.

Основные понятия

Графики вызовов могут быть динамическими или статическими. Динамический график вызовов представляет собой запись выполнения программы, например, полученную с помощью профилировщика. Таким образом, динамический график вызовов может быть точным, но описывает только один конкретный запуск программы. Статический график вызовов предназначен для представления всех возможных запусков программы. Вычисление точного статического графика вызовов является неразрешимой задачей, поэтому алгоритмы построения статических графиков вызовов обычно представляют собой переоценки. Это означает, что в графике отображаются все фактические отношения вызовов, а также, возможно, некоторые отношения вызовов, которые никогда не произойдут при реальном выполнении программы. Графики вызовов могут быть определены с разной степенью точности. Более точный график вызовов точнее аппроксимирует поведение реальной программы, но требует больше времени на вычисление и больше памяти для хранения. Наиболее точный график вызовов является полностью контекстно-зависимым, что означает, что для каждой процедуры в графе содержится отдельный узел для каждого стека вызовов, с которым эта процедура может быть активирована. Полностью контекстно-зависимый график вызовов называется деревом контекста вызовов. Его можно легко вычислить динамически, хотя это может потребовать значительного объема памяти. Деревья контекста вызовов обычно не вычисляются статически, поскольку для больших программ это заняло бы слишком много времени. Наименее точный график вызовов является контекстно-независимым, что означает, что для каждой процедуры существует только один узел. Для языков с динамической диспетчеризацией (например, Java или C++), функциями первого класса (например, Python или Racket) или указателями на функции (например, C), точное вычисление статического графика вызовов требует результатов анализа псевдонимов. И наоборот, для вычисления точного анализа псевдонимов требуется график вызовов. Многие системы статического анализа разрешают эту кажущуюся бесконечную регрессию, вычисляя оба компонента одновременно.

Использование

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

Другие, связанные с ними инструменты

Graphviz Преобразует текстовое представление любого графа (включая граф вызовов) в изображение. tsort Утилита командной строки для выполнения топологической сортировки.