Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ZH ос 20 вопр 36 стр.doc
Скачиваний:
11
Добавлен:
20.09.2019
Размер:
435.71 Кб
Скачать
  1. Стек потока под управлением Windows nt (2000).

Стек потока.

О

программный сегмент

сегмент данных

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

Рассмотрим стек Windows NT, 2000. Под стек по умолчанию выделяется регион размером 1 Мб и передаются две страницы физической памяти. Значения устанавливаемые по умолчанию можно изменять в программе. Размер физической памяти можно менять при вызове функции CreateThread(…). Так выглядит стек при создании:

Страница физической памяти | PAGE_READWRITE

Страница физической памяти | PAGE_GUARD

c флагом

Зарезервированная страница |

. |

. |

. |

Зарезервированная страница |

. |

. |

. |

Программный код |

0 80FF000

0 8000000

Указатель стека устанавливается в верхней части стека. Физическая память выделена двум страницам.

Вторая страница имеет флаг запрещения доступа.

По мере создания различных локальных переменных стек разрастается, по мере его заполнения происходит переход во вторую страницу. Но эта страница защищена. ОС будет извещена о попытке записи на защищенную страницу и обрабатывает её следующим образом: снимает флаг запрещения записи со второй старницы. Выделяет стеку третью страницу физической памяти и присваивает третьей странице атрибуты PAGE_READWRITE и флаг PAGE_GUARD.

Рассмотрим ситуацию, когда стек потока фактически заполнен.

////////////////////////////

PAGE_GUARD

3арезервированная страница

Зарезервированная страница

ОС выполняет следующее:

Флаг PAGE_GUARD снимается и физическая память выделяется следующей странице.

Физическая

память

После этого ОС формирует исключение, то есть информирует процесс о Stack Overflow. В этом случае процесс должен среагировать, если этого не произойдёт, то производится попытка записи на зарезервированную страницу, то есть когда это происходит, то ОС берёт управление на себя и завершает не только данный поток, а и весь процесс. В этом случае ОС даже не извещает пользователя. Процесс исчезает бесследно.

Почему нижняя страница стека всегда остаётся зарезервированной?

  1. Для того, чтобы защитить стек от перезаписи.

Стек

Зарезервированная страница

Данные

Физическая

память

Физическая

память

  1. Для защиты программ и данных при переполнении стека. Например,

Стек

Пароли

Физическая

память

Стираем пароли и получаем доступ к сети.

  1. Кучи. Кучи в Windows nt (2000).

Куча – 3-й и последний элемент управления памятью в Win32. Используется для создания небольших блоков данных, например связанных с очередями, списками, деревьями.

В DOS и Win16 кучи играли основную роль, в Win32 – вспомогательную.

Особенности куч Win32:

  • максимальный размер кучи не ограничен, т.е. теоретически = макс. адресное пространство процесса (2 ГБ)

  • кучи могут расти за пределы изначально выделенного им пространства. В этом случае выделяется блок АП и связывается с кучей, образуя подкучу

  • поддерживается несколько куч в рамках данного процесса

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

  • все кучи – локальные, т.е. каждая куча принадлежит определенному процессу

  • п ри создании процесса обязательно создается одна куча – куча, предоставляемая процессу по умолчанию. Она уничтожается только при закрытии процесса.

Структура куч Win32:

Доп. кучи создаются с помощью HeapCreate. Используются для защиты компонентов, для более эффективного управления памятью, для локализации доступа.

Каждый блок имеет свой заголовок – арену. Заголовок кучи имеет следующую структуру. Заголовок состоит из полей.

  1. общий размер памяти, зарезервированной для кучи.

  2. указатель на следующую кучу, если она есть.

  3. указатель на начало списка дополнительных подкуч данной кучи.

  4. списки свободных блоков.

Для снижения фрагментации памяти и ускорения поиска свободных блоков заголовок каждой кучи содержит 4 списка свободных блоков:

1-ый список состоит из блоков, размер которых меньше 20h байт.

2-ой список - меньше 80h байт.

3-ий список - меньше 200h байт.

4-ый список - меньше FFFFFFFFh байт.

Функции работы с кучей.

GetProcessHeap(…) – получить дескриптор кучи, предоставляемый процессу по умолчанию. Эта функция находит PDB и извлекает из базы данных дескриптор кучи.

HeapCreate(…) – создание кучи. Вызывают не только приложения пользователя, но и kernel32.dll и user32.dll вызывает для создания системных структур данных, например PDB или базы данных потока (TDB).

Процесс создания кучи проходит в 2 этапа: резервирование памяти для кучи и связывание кучи в списке куч процесса, инициализация всех полей заголовка кучи.

Удаление кучи.

HeapDestroy(…). Проблема состоит в том, что

  1. куча должна быть свободной, то есть CriticalSection=0.

  2. куча может иметь подкучи.

Необходимо удалить весь список связанных подкуч. то есть HeapDestroy(…) должна выполнять действия по корректировке списка.

Выделение блока памяти в определённой куче.

HeapAlloc(…). Этот процесс состоит из следующих этапов.

  1. проверки параметров функции HeapAlloc(…).

  2. захват CriticalSection заголовка кучи.

  3. выравнивание размера запрошенного блока к ближайшему числу кратному 4 и добавление размера арены.

  4. нахождение первого свободного блока в списке. Если блок найден, то функция проверяет насколько этот блок велик. Если можно поделить на 2, то создаются 2 блока, настраиваются их арены. Первый блок занят функцией HeapAlloc(…), другой поступает в список свободных блоков.

  5. освобождение критической секции. Указатель кучи устанавливается на первый байт следующего за ареной блока. Если функция не найдёт в списке подходящего свободного блока, то kernel32 создаёт подкучу, вставляет в список подкуч, а затем функция HeapAlloc(…) возвращается к поиску свободных блоков.

Освобождение блока кучи.

  1. HeapFree(…).

  2. проверка параметров.

  3. захват CriticalSection.

  4. если перед освобождаемым блоком уже есть свободный блок, то сливаются в один.

  5. фактическое освобождение блока, возврат его в кучу.

  6. освобождение CriticalSection.

Куча, предоставляемая процессу по умолчанию.

Данную кучу нельзя уничтожить (создается при создании процесса, уничтожается при завершении процесса). Данную кучу помимо пользователя используют функции Win32.