Ада-95. Компилятор GNAT

       

Средства GNATDebug_Pools


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

может легко привести к некорректным ссылкам памяти.

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

В подобных случаях, очень важно обнаружить наличие подобной проблемы как можно раньше.

Именно такая задача возлагается на Storage_Pool предусмотренный в GNAT.Debug_Pools.

Чтобы воспользоваться средствами отладочного пула динамической памяти GNAT, пользователь должен ассоциировать объект отладочного пула с каждым ссылочным типом, который потенциально способен быть источником проблем.

type Ptr is access Some_Type; Pool : GNAT.Debug_Pools.Debug_Pool; for Ptr'Storage_Pool use Pool;

GNAT.Debug_Pool является производным от Checked_Pool, который является характерным для GNAT пулом динамической памяти.

Такие пулы динамической памяти, подобно стандартным пулам динамической памяти Ады, позволяют пользователю переопределять стратегию распределения (аллокацию) и освобождения (деаллокацию) динамической памяти.

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

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



GNAT.Debug_Pools.Accessing_Not_Allocated_Storage

GNAT.Debug_Pools.Accessing_Deallocated_Storage

GNAT.Debug_Pools.Freeing_Not_Allocated_Storage

GNAT.Debug_Pools.Freeing_Deallocated_Storage

Для типов, ассоциированных с отладочным пулом Debug_Pool

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

Ссылки ко всем фрагментам распределенной памяти сохраняются во внутреннем каталоге.

Стратегия освобождения состоит не в освобождении памяти используемой системы, а в заполнении памяти шаблоном, который может быть легко распознан в процессе отладочной сессии.




Шаблон соответствует старому двоично десятичному соглашению IBM и имеет значение 16#DEADBEEF#.

При каждом разыменовании, осуществляется проверка того, что ссылочное значение указывает на правильно распределенное место памяти.

Ниже показан полный пример использования отладочного пула Debug_Pool, который содержит типичный образец разрушения памяти:

@leftskip=0cm with Gnat.Io; use Gnat.Io; with Unchecked_Deallocation; with Unchecked_Conversion; with GNAT.Debug_Pools; with System.Storage_Elements; with Ada.Exceptions; use Ada.Exceptions; procedure Debug_Pool_Test is

type T is access Integer; type U is access all T;

P : GNAT.Debug_Pools.Debug_Pool; for T'Storage_Pool use P;

procedure Free is new Unchecked_Deallocation (Integer, T); function UC is new Unchecked_Conversion (U, T); A, B : aliased T;

procedure Info is new GNAT.Debug_Pools.Print_Info(Put_Line);

begin

Info (P); A := new Integer; B := new Integer; B := A; Info (P); Free (A); begin

Put_Line (Integer'Image(B.all)); exception

when E : others => Put_Line ("raised: " & Exception_Name (E)); end; begin

Free (B); exception

when E : others => Put_Line ("raised: " & Exception_Name (E)); end; B := UC(A'Access); begin

Put_Line (Integer'Image(B.all)); exception

when E : others => Put_Line ("raised: " & Exception_Name (E)); end; begin

Free (B); exception

when E : others => Put_Line ("raised: " & Exception_Name (E)); end; Info (P); end Debug_Pool_Test;

Механизм отладочного пула предусматривает отображение следующей диагностики, при выполнении показанной выше программы с ошибками:

Debug Pool info: Total allocated bytes : 0 Total deallocated bytes : 0 Current Water Mark: 0 High Water Mark: 0

Debug Pool info: Total allocated bytes : 8 Total deallocated bytes : 0 Current Water Mark: 8 High Water Mark: 8

raised: GNAT.DEBUG_POOLS.ACCESSING_DEALLOCATED_STORAGE raised: GNAT.DEBUG_POOLS.FREEING_DEALLOCATED_STORAGE raised: GNAT.DEBUG_POOLS.ACCESSING_NOT_ALLOCATED_STORAGE raised: GNAT.DEBUG_POOLS.FREEING_NOT_ALLOCATED_STORAGE Debug Pool info: Total allocated bytes : 8 Total deallocated bytes : 4 Current Water Mark: 4 High Water Mark: 8


Содержание раздела