debugDDr (1158410), страница 3
Текст из файла (страница 3)
Каждая запись таблицы содержит следующую информацию о переменной: адрес, уровень исполнения программы, в котором эта запись была создана, класс использования переменной и дополнительная информация, определяемая классом использования.
Рис. 2. Структура таблицы переменных
Для хранения информации о переменной используется следующая структура:
| typedef struct tag_VarInfo | ||||
| { | ||||
| byte | Busy; | |||
| void * | VarAddr; | |||
| long | PrevNo; | |||
| int | EnvirIndex; | |||
| byte | Type; | |||
| SysHandle * | Handle; | |||
| void * | Info; | |||
| int | Tag; | |||
| byte | IsInit; | |||
| PFN_VARTABLE_ELEMDESTRUCTOR | pfnDestructor; | |||
| } | VarInfo; | |||
| Busy | – | флаг, указывающий свободна эта структура или нет. Служит для оптимизации операций с таблицей переменных; | ||
| VarAddr | – | адрес переменной; | ||
| PrevNo | – | номер элемента таблицы переменных, описывающий ту же переменную в другом контексте выполнения; | ||
| EnvirIndex | – | номер уровня исполнения программы для данной переменной; | ||
| Type | – | класс переменной; | ||
| Handle | – | указатель на дескриптор распределенного массива. Неравен NULL, если структура описывает распределенный массив; | ||
| Info | – | указатель на дополнительное описание переменной; | ||
| Tag | – | флаг для хранения различных атрибутов переменной в зависимости от класса ее использования; | ||
| IsInit | – | флаг инициализации переменной. Используется для скалярных переменных; | ||
| pfnDestructor | – | указатель на деструктор описания переменной. Данная функция будет вызвана при удалении описания переменной из таблицы переменных. Может быть равен NULL. | ||
Следующая структура описывает таблицу переменных:
| typedef struct tag_VAR_TABLE | ||||
| { | ||||
| HASH_TABLE | hIndex; | |||
| TABLE | vTable; | |||
| } | VAR_TABLE; | |||
| hIndex | – | хеш-таблица для поиска информации о переменной по ее адресу; | ||
| vTable | – | таблица для хранения описаний переменных. | ||
Прототипы функций для работы с таблицей переменных:
| void vartable_Init( VAR_TABLE *VT, int vTableSize, int hIndexSize, int hTableSize, PFN_CALC_HASH_FUNC Func ) | ||
| VT | – | указатель на таблицу переменных; |
| vTableSize | – | размер приращения таблицы vTable; |
| hIndexSize | – | размер массива индексов хеш-таблицы hIndex; |
| hTableSize | – | размер приращения хеш-таблицы hIndex; |
| Func | – | указатель на функцию, используемую для вычисления хеш-значения по адресу переменной. |
Функция инициализирует таблицу переменных.
| void vartable_Done( VAR_TABLE *VT ); | ||
| VT | – | указатель на таблицу переменных |
Деструктор таблицы переменных.
| VarInfo *vartable_GetVarInfo( VAR_TABLE *VT, long NoVar ) | ||
| VT | – | указатель на таблицу переменных; |
| NoVar | – | номер переменной в таблице. |
Функция осуществляет поиск информации о переменной по ее номеру. Возвращает указатель на структуру с описанием переменной.
| VarInfo *vartable_FindVar( VAR_TABLE *VT, void * Addr ) | ||
| VT | – | указатель на таблицу переменных; |
| Addr | – | адрес переменной. |
Функция осуществляет поиск информации о переменной по ее адресу. Возвращает указатель на структуру с описанием переменной или NULL, если переменная с таким адресом не зарегистрирована.
| long vartable_FindNoVar( VAR_TABLE *VT, void * Addr ) | ||
| VT | – | указатель на таблицу переменных; |
| Addr | – | адрес переменной. |
Функция осуществляет поиск номера переменной в таблице по ее адресу. Возвращает номер переменной в таблице или -1, если переменная с таким адресом не зарегистрирована.
| long vartable_PutVariable(VAR_TABLE* VT, void* Addr, int Env, byte Type, SysHandle* Handle, int Tag, void* Info, PFN_VARTABLE_ELEMDESTRUCTOR pfnDestructor) | ||
| VT | – | указатель на таблицу переменных; |
| Addr | – | адрес переменной; |
| Env | – | номер уровня выполнения; |
| Type | – | тип использования переменной; |
| Handle | – | дескриптор распределенного массива при его регистрации; |
| Tag | – | значение дополнительного атрибута переменной; |
| Info | – | указатель на дополнительную информацию; |
| pfnDestructor | – | указатель на деструктор описания переменной. Может быть равен NULL. |
Функция регистрирует новую переменную в таблице. Возвращает номер зарегистрированной переменной.
| void vartable_VariableDone( VarInfo* Var ) | ||
| Var | – | указатель на описание переменной. |
Функция вызывается для деинициализации описания переменной. Устанавливает флаг Busy в 0 и, при необходимости, вызывает соответствующий деструктор.
| void vartable_RemoveVariable( VAR_TABLE *VT, void * Addr ) | ||
| VT | – | указатель на таблицу переменных; |
| Addr | – | адрес удаляемой переменной. |
Функция удаляет описание переменной из таблицы переменных.
| void vartable_RemoveAll( VAR_TABLE *VT ); | ||
| VT | – | указатель на таблицу переменных. |
Функция удаляет описания всех переменных из таблицы переменных.
| void vartable_RemoveVarOnLevel( VAR_TABLE *VT, int Level ) | ||
| VT | – | указатель на таблицу переменных |
| Level | – | номер уровня выполнения |
Функция удаляет описание всех переменных с указанным уровнем исполнения.
| void vartable_Iterator( VAR_TABLE *VT, PFN_VARTABLEITERATION Func ) | ||
| VT | – | указатель на таблицу переменных; |
| Func | – | итерационная функция с прототипом: void (*PFN_VARTABLEITERATION)(VarInfo *). Функции будут переданы все указатели на описания переменных в таблице переменных. |
Функция выполняет однотипную операцию над всеми описаниями переменных из таблицы переменных.
| void vartable_LevelIterator(VAR_TABLE* VT, int Level, PFN_VARTABLEITERATION Func) | ||
| VT | – | указатель на таблицу переменных; |
| Level | – | номер уровня выполнения; |
| Func | – | итерационная функция с прототипом: void (*PFN_VARTABLEITERATION)(VarInfo *). Функции будут по очереди переданы все указатели на описания переменных в таблице переменных, имеющих указанный номер контекста выполнения. |
Функция выполняет однотипную операцию над всеми описаниями переменных указанного уровня исполнения из таблицы переменных.
4.4Модуль выдачи диагностики
К модулю выдачи диагностики предъявляются следующие требования. Во-первых, при выдаче сообщения о найденной ошибке должен быть выведен достаточно подробный контекст, в котором данная ошибка была обнаружена. Во вторых, при динамическом контроле необходимо предотвратить выдачу большого количества диагностик об одной и той же ошибке, что неизбежно произойдет при наличии ошибочного оператора в теле цикла. Наконец, необходимо позволить пользователю выводить диагностику, как на экран, так и в файл, с целью последующего анализа.
Модуль диагностики состоит из двух блоков. Блок обработки контекста отслеживает текущий контекст выполнения программы и позволяет получить подробное описание текущего контекста для диагностики. Блок выдачи диагностики занимается выдачей диагностики и фильтрацией однотипных сообщений.
4.4.1Обработка контекста диагностики
Контекст выполнения программы представляет собой описание всех исполняемых в текущий момент циклов программы вместе со значениями индексов цикла или параллельных задач. Текущий контекст меняется каждый раз, когда начинается или завершается параллельный или последовательный цикл или область задач, начинается выполнение нового витка или новой задачи.















