﻿# Межмодульный анализ

Продвинутые статические анализаторы учитывают данные, которые передаются между процедурами/функциями, чтобы выявить большее количество ошибок и дефектов безопасности\. Это важно при выявлении таких ошибок, как выход за границу буфера, утечка конфиденциальных данных \(анализ помеченных данных\), разыменование нулевых указателей и т\.д\. Связано это с тем, что создание некого ресурса, его использование и освобождение часто разнесены по разным функциям\.

Для выявления ошибок, возникающих при взаимодействии нескольких процедур, статические анализаторы используют технологию [межпроцедурного контекстно\-чувствительного анализа кода](https://pvs-studio.ru/ru/blog/terms/6785/)\. Если эти функции находятся в разных программных модулях, то необходимо использовать **межмодульный анализ**\.

Рассмотрим пример ошибки, найденной с помощью межмодульного анализа инструментом PVS\-Studio в коде проекта Midnight Commander \(язык C\)\.

Начнём с функции _widget\_destroy_ в файле widget\-common\.c:

```cpp
void widget_destroy (Widget * w)
{
  send_message (w, NULL, MSG_DESTROY, 0, NULL);
  g_free (w);
}
```

Для нас важно, что функция освобождает буфер памяти, адрес которого она получает через аргумент _w_\.

Теперь посмотрим на код в файле editcmd\.c:

```cpp
gboolean edit_close_cmd (WEdit * edit)
{
  Widget *w = WIDGET (edit);
  ....
  widget_destroy (w);     // <= Здесь освободили память
  if (....) .... else
  {
    edit = find_editor (DIALOG (g));
    if (edit != NULL)
      widget_select (w);  // <= Сейчас заглянем внутрь
  }
}
```

Обратите внимание, что в начале адрес структуры _Widget_ передаётся в функцию _widget\_destroy_, где происходит освобождение буфера памяти\. Далее этот указатель передаётся в функцию _widget\_select_, приведённую ниже:

```cpp
void widget_select (Widget * w)
{
  WGroup *g;
  if (!widget_get_options (w, WOP_SELECTABLE))
    return;
  ....
}
```

Она просто передаёт указатель дальше в функцию _widget\_get\_options_:

```cpp
static inline gboolean
widget_get_options (const Widget * w, widget_options_t options)
{
  return ((w->options & options) == options);
}
```

Здесь мы добрались до места, где возникает неопределённое поведение, связанное с использованием данных в уже освобождённом буфере памяти\. Анализатор PVS\-Studio сигнализирует об этом предупреждением: 

[V774](https://pvs-studio.ru/ru/docs/warnings/v774/) The 'w' pointer was used after the memory was released\.

Это относительно простой случай, где было задействованы только два файла: widget\-common\.c и editcmd\.c\. Ошибки могут быть выявлены и в более длинных цепочках вызова процедур, расположенных в трёх и более файлах\. Однако на практике у статических анализаторов есть ограничения на глубину анализа вызовов\. Они связаны как с теоретическими сложностями \([проблема остановки](https://ru.wikipedia.org/wiki/%D0%9F%D1%80%D0%BE%D0%B1%D0%BB%D0%B5%D0%BC%D0%B0_%D0%BE%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B8)\), так и практическими \(большая вычислительная сложность\)\. Поэтому статический анализ кода [полезно дополнять динамическим](https://pvs-studio.ru/ru/blog/posts/0643/)\.

<details>
   <summary>Определение межмодульного анализа по ГОСТ Р 71207\\\-2024\\\.</summary>

[ГОСТ Р 71207\-2024](https://pvs-studio.ru/ru/pvs-studio/gost-71207/) — Статический анализ программного обеспечения\. В разделе терминов дано следующее определение межмодульного анализа:

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


</details>
**Дополнительные ссылки**

1. [Статический анализ кода](https://pvs-studio.ru/ru/blog/terms/0046/)\.
1. Андрей Карпов\. [Как работает статический анализ](https://pvs-studio.ru/ru/blog/posts/1048/)?
1. Олег Лысый, Сергей Ларин\. [Межмодульный анализ C\+\+ проектов в PVS\-Studio](https://pvs-studio.ru/ru/blog/posts/cpp/0851/)\.
1. Доклад на C\+\+Russia\. Олег Лысый\. [Межмодульный анализ C\+\+ проектов](https://pvs-studio.ru/ru/blog/video/10834/)\.
1. Олег Лысый\. Межмодульный анализ C и C\+\+ проектов в деталях\. [Часть 1](https://pvs-studio.ru/ru/blog/posts/cpp/0963/)\. [Часть 2](https://pvs-studio.ru/ru/blog/posts/cpp/0965/)\.
1. Андрей Карпов\. [Что нельзя найти с помощью статического анализа](https://pvs-studio.ru/ru/blog/posts/1037/)\.