Skip to content

NimblePython/seminar-1

Repository files navigation

Задание: "Анализ жизненного цикла программы и образа памяти на примере многомодульного проекта на C++"

Цель:

Создать многомодульный проект на C++, который продемонстрирует жизненный цикл программы: от этапа препроцессинга до запуска и завершения, с детализированным анализом стека, кучи, глобальных и локальных переменных, а также с использованием виртуальной и физической памяти. Необходимо продемонстрировать результат работы различных инструментов, таких как gcc, objdump, nm, gdb и других для анализа программы.

Структура задания:

1. Создание многомодульного проекта

  • Проект должен состоять из нескольких файлов с исходным кодом и хедеров.
  • Основные файлы проекта:
    • main.cpp: основной файл программы.
    • utils.h и utils.cpp: заголовочный и исходный файлы с набором утилитарных функций.
    • data.h и data.cpp: заголовочный и исходный файлы для работы с глобальными и статическими переменными.

Пример структуры программы:

  • main.cpp:

    • Инициализация глобальных, статических и локальных переменных.
    • Вызов функций из других модулей.
    • Демонстрация r-value и l-value в различных контекстах.
    • Вызов функции, которая работает с виртуальной памятью и показывает PID процесса.
  • utils.h / utils.cpp:

    • Функции для работы с локальными переменными.
    • Функции, демонстрирующие вызов по ссылке, копии и перемещению.
  • data.h / data.cpp:

    • Глобальные и статические переменные, их инициализация.
    • Демонстрация работы с сегментом .rodata (например, попытка изменить данные в сегменте только для чтения).

2. Этапы жизненного цикла программы

2.1 Этап препроцессинга

  • Необходимо запустить препроцессор с помощью команды g++ -E.
  • Проанализировать результат работы препроцессора: объединение хедеров, макросы и замены.
  • Задание: выявить, что конкретно изменилось после этапа препроцессинга.

2.2 Этап компиляции

  • Скомпилировать каждый файл в объектные файлы (g++ -c).
  • Задание: продемонстрировать таблицу символов в объектных файлах с помощью nm.
  • Объяснить, какие символы находятся в таблице и как они отражают различные сегменты программы (код, данные, rodata).

2.3 Этап линковки

  • Связать объектные файлы в исполняемый файл.
  • Проанализировать сгенерированный бинарный файл с помощью objdump.
  • Задание: показать, как работают динамические и статические линковки, и чем они отличаются.

2.4 Этап запуска

  • Запустить программу и показать PID процесса с помощью системного вызова.
  • С помощью gdb или strace проанализировать, как происходит инициализация глобальных переменных, какой код выполняется до входа в main.
  • Задание: попытаться изменить данные в сегменте .rodata и объяснить результат.

2.5 Анализ стека и кучи

  • В программе намеренно вызвать несколько функций, работающих с локальными переменными, и проанализировать стек с помощью gdb.
  • Задание: с помощью отладчика проанализировать структуру стека вызовов, показать переменные и их значения на стеке.

2.6 Анализ виртуальной памяти

  • Используя системные вызовы, показать карты памяти процесса (/proc/[pid]/maps).
  • Задание: объяснить распределение памяти между стеком, кучей, сегментами кода и данных.

3. Дополнительные задачи

  • Реализовать возможность перемещения данных между различными сегментами памяти.
  • Реализовать функции с явным использованием r-value и l-value ссылок, чтобы продемонстрировать семантику перемещения.
  • Программа должна использовать статические и динамические библиотеки, и студенты должны проанализировать разницу в линковке и загрузке.

Инструменты для анализа:

  • gcc/g++ — для препроцессинга, компиляции и линковки.
  • objdump — для анализа объектных и исполняемых файлов.
  • nm — для отображения таблицы символов.
  • gdb — для анализа стека и отладки программы.
  • strace — для анализа системных вызовов программы.
  • valgrind — для анализа утечек памяти и работы с кучей.
  • /proc/[pid]/maps — для анализа карты памяти запущенного процесса.

Итоговый результат:

  • Продемонстрировать, как программа проходит через все этапы жизненного цикла.
  • Предоставить отчет, показывающий, как каждая переменная инициализируется в соответствующих сегментах памяти.
  • Провести анализ таблицы символов, показать стек вызовов и сегменты памяти программы.
  • Описать процесс запуска программы, объяснив, что происходит до вызова функции main.

Дополнительные возможности:

  • Попробовать редактировать память программы в реальном времени с помощью отладчика.
  • Исследовать механизм динамической линковки и попробовать заменить динамическую библиотеку во время выполнения программы.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published