Курынин Р.В., Машечкин И.В., Терехин А.Н. - Конспект лекций по ОС (1114685), страница 36
Текст из файла (страница 36)
Адресно-кодовыеотладчики оперируют адресами тела отлаживаемого процесса, в то время как символьныеотладчики позволяют оперировать объектами языка, т.е. переменными языка и операторами языка.Механизм организации контрольной точки в адресно-кодовом отладчике достаточнопростой. Пускай нам необходимо по некоторому адресу A установить контрольную точку, т.е.чтобы при приходе управления в эту точку программы процесс всегда приостанавливался, иуправление передавалось процессу-отладчику. В отладчике имеется таблица контрольных точек, вкаждой строке которой присутствует адрес некоторой контрольной точки и оригинальный кодотлаживаемого процесса, взятый по данному адресу.
Для установки контрольной точки по адресуA необходимо тем или иным способом остановить отлаживаемый процесс (либо оностанавливается при входе, либо отладчик посылает ему соответствующий сигнал). Затемотладчик читает из сегмента кода машинное слово по адресу A (посредством обращения ксистемному вызову ptrace()), которое он записывает в соответствующую строку таблицыконтрольных точек, тем самым, сохраняя оригинальное содержимое тела трассируемого процесса.Далее по адресу A в сегмент кода записывается команда, которая вызывает прерывание и,140соответственно, приход предопределенного события.
Примером может служить команда деленияна ноль. После этого запускаем отлаживаемый процесс на исполнение.Итак, трассируемый процесс исполняется, и управление, наконец, передается на машинноеслово по адресу A. Происходит деление на ноль. Соответственно, происходит прерывание,система передает сигнал. И отладчик через системный вызов wait() получает код возврата и«понимает», что в дочернем процессе случилось деление на ноль. Отладчик посредствомсистемного вызова ptrace() читает адрес остановки в контексте дочернего процесса. Далееанализируется причина остановки.
Если причина остановки явилось деление на ноль, то возможныдве ситуации: это действительно деление на ноль, как ошибка, либо деление на ноль, какконтрольная точка. Для идентификации этой ситуации отладчик обращается к таблицеконтрольных точек и ищет там адрес останова подчиненного процесса. Если в данной таблицеуказанный адрес встретился, то это означает, что отлаживаемый процесс пришел на контрольнуюточку (иначе деление на ноль отрабатывается как ошибка).Находясь в контрольной точке, отладчик может производить различные манипуляции страссируемым процессом (читать данные, устанавливать новые контрольные точки и т.п.).
Далеевстает вопрос, как корректно продолжить подчиненный процесс. Для этого производитсяследующие действия. По адресу A записывается оригинальное машинное слово. После этогосистемным вызовом ptrace() включаем шаговый режим. И выполняем одну команду (которуютолько что записали по адресу A). Из-за включенного режима пошаговой отладки подчиненныйпроцесс снова остановится. Затем отладчик выключает режим пошаговой отладки и запускаетпроцесс с текущей точки.Для организации контрольных точек в символьных отладчиках необходима информация,собранная на этапах компиляции и редактирования связей. Если с компилятором связансимвольный отладчик, то компилятор формирует некоторую специализированную базу данных, вкоторой находится информация по всем именам, используемым в программе.
Для каждого имениопределены диапазоны видимости и существования этого имени, его тип (статическая переменная,автоматическая переменная, регистровая переменная и т.п.). А также данная база содержитинформацию обо всех операторах (диапазон начала и конца оператора, и т.п.).Предположим, необходимо просмотреть содержимое некоторой переменной v. Для этоготрассируемый процесс должен быть остановлен. По адресу останова можно определить, в какойточке программы произошел останов. На основании информации об этой точке программы можно,обратившись к содержимому базы данных, определить то пространство имен, доступных из этойточки.
Если интересующая нас переменная v оказалась доступна, то продолжается работа:происходит обращение к базе данных и определяется тип данной переменной. Если типпеременной v — статическая переменная, то в соответствующей записи будет адрес, по которомуразмещена данная переменная (этот адрес станет известным на этапе редактирования связей). И спомощью ptrace() отладчик берет содержимое по этому адресу. Также из базы данных беретсяинформация о типе переменной (char, float, int и т.п.), и на основе этой информации пользователюсоответствующим образом отображается значение указанной переменной v.Пускай переменная v оказалась автоматической переменной или формальным параметром.Переменные этих типов обычно реализуются в вершине стека (т.е. для этих переменных вкачестве адреса фиксируется смещение от вершины стека).
Чтобы прочитать содержимоепеременной подобного типа, необходимо обратиться к контексту процесса, считать значениерегистра-указателя на стек, после этого к содержимому регистра прибавить смещение, и пополучившемуся адресу обратиться к соответствующему сегменту.Если переменная v — регистровая переменная, то происходит обращение к базе данных,считывается номер регистра, затем идет обращение к сегменту кода и считывается содержимоенужного регистра.Для записи значений в переменные происходит та же последовательность действий.Если необходимо установить контрольную точку на оператор, то через базу данныхопределяется диапазон адресов оператора, определяется начальный адрес, а дальше производятсядействия по описанной выше схеме.1413.2Системамежпроцессного(Inter-Process Communication)взаимодействияIPCСистема IPC (известная так же, как IPC System V) позволяет обеспечивать взаимодействиепроизвольных процессов в пределах локальной машины.
Для этого она предоставляетвзаимодействующим процессам возможность использования общих, или разделяемых, ресурсовтрех типов.− Общая, или разделяемая, память, которая представляется процессу как указатель на областьпамяти, которая является общей для двух и более процессов. Т.е. внутри процесса некоторыйуказатель можно установить на начало данной области и работать далее с этой областью, как смассивом. Все изменения, которые сделает данный процесс, будут видны другим процессам.Разделяемая память IPC почти не обладает никакими средствами синхронизации (т.е.существует очень слабо развитый механизм взаимных блокировок, но мы на нем не будемостанавливаться).− Массив семафоров — ресурс, представляющий собой массив из N элементов, где N задаетсяпри создании данного ресурса, и каждый из элементов является семафором IPC (а несемафором Дейкстры: семафор Дейкстры так или иначе является формализмом, неопирающимся ни на какую реализацию, а семафор IPC — конкретной программнойреализацией в ОС).
Семафоры IPC предназначены, в первую очередь, для использования вкачестве средств организации синхронизации.− Очередь сообщений — это разделяемый ресурс, позволяющий организовывать очередисообщений: один процесс может в эту очередь положить сообщение, а другой процесс —прочитать его. Данный механизм имеет возможность блокировок, поэтому его можноиспользовать и как средство передачи информации между взаимодействующими процессами,и как средство их синхронизации.Для организации совместного использования разделяемых ресурсов необходим некоторыймеханизм именования ресурсов, используя который взаимодействующие процессы смогутработать с данным конкретным ресурсом.
Для этих целей используется система ключей: присоздании ресурса с ним ассоциируется ключ — целочисленное значение. Жесткого ограничения квыбору этих ключей нет. Т.е. при создании ресурса, предположим, общая память процесссоздатель ассоциирует с ним конкретный ключ — например, 25. Теперь все процессы, желающиеработать с той же общей памятью, должны, во-первых, обладать соответствующими правами, а вовторых, заявить, что они желают работать с ресурсом общая память с ключом 25. И они будут сней работать. Но тут возможны коллизии из-за случайного совпадения ключей различныхресурсов.Во избежание коллизий система предлагает некоторую унификацию именования IPCресурсов. Для генерации уникальных ключей в системе имеется библиотечная функция ftok().#include <sys/types.h>#include <sys/ipc.h>key_t ftok(char *filename, char proj);Первый параметр данной функции — полное имя существующего файла.
Второйпараметр — это уточняющая информация (в частности, он может использоваться для поддержанияразных версий программы).Итак, функция ftok() обращается к указанному файлу, считывает его атрибуты и, используязначение второго аргумента, генерирует уникальный ключ (уникальное целое число). Стоит особообратить внимание, что первый параметр должен указывать на существующий файл, и, что не142менее важно, при генерации ключа используются его атрибуты. Это означает, что если одинпроцесс для генерации ключа ссылается на некоторый файл, создает ресурс, потом этот файлуничтожается, создается другой файл с тем же именем (но, скорее всего, с другими атрибутами),то другой процесс, желающий получить ключ к созданному ресурсу, не сможет этого сделать, т.к.функция ftok() будет генерировать иное значение.Каждый ресурс IPC имеет атрибут владельца.
Владельцем считается тот процесс (егоидентификация), который создал данный ресурс, и, соответственно, удалить данный ресурс можеттолько владелец. Но стоит отметить, что существует механизм передачи прав владения отпроцесса процессу.С каждым ресурсом, так же как и с файлами, связаны три категории прав (права владельца,группы и остальных пользователей). Но в каждой категории имеются лишь права на чтение изапись: право на выполнение нет.Ресурсы IPC могут существовать без процессов, их создавших. Это означает, чтосозданный разделяемый ресурс будет существовать до тех пор, пока его явно не удалят либо доперезапуска системы.Итак, имеется три группы IPC-ресурсов, с каждой из которой связан свой набор функцийпо работе с конкретным типом ресурса.