Отладка

Отладка

Один из худших сеансов отладки за всю мою карьеру случился в 1972 году. Терминалы, подключенные к бухгалтерской системе профсоюза грузоперевозчиков, зависали один-два раза в день. Сознательно воспроизвести ошибку было невозможно. Ошибка не отдавала предпочтений какому-то конкретному терминалу или приложению. Не важно, чем занимался пользователь перед зависанием: сейчас терминал работает нормально, а в следующую минуту безнадежно зависает.

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

Первая пара недель была проведена за простым опросом пользователей, работавших за зависающими терминалами. Мы спрашивали, чем они занимались в тот момент и что делалось до этого. Мы спрашивали других пользователей, не заметили ли они чего-нибудь необычного на своих терминалах в момент зависания. Собеседования приходилось проводить по телефону, потому что терминалы были установлены в пригородах Чикаго, а мы работали на 30 миль к северу.

У нас не было журналов, счетчиков или отладчиков. Все взаимодействие с внутренним состоянием системы осуществлялось через индикаторы и тумблеры передней панели. Мы могли остановить компьютер и просмотреть содержимое памяти по словам. Однако заниматься этим более 5 минут было невозможно, потому что грузоперевозчикам была нужна их система.

Мы потратили несколько дней на написание простого инспектора, работавшего в режиме реального времени. Им можно было управлять с телетайпа ASR-33, который служил нам консолью. Инспектор позволял читать и изменять содержимое памяти во время работы системы.

Мы добавили журнальные сообщения, которые выводились на телетайп в критических ситуациях. Мы создали в памяти счетчики событий, которые запоминали информацию состояний для ее просмотра инспектором. И конечно, весь код создавался «с нуля» на ассемблере и тестировался по вечерам, когда система не использовалась.

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

Со временем выяснилось, что терминал зависал из-за рассинхронизации трех переменных, управлявших циклическим буфером. Мы понятия не имели, почему это происходило, но это было хоть что-то. Где-то в 5K строк кода супервизора содержалась ошибка, которая некорректно работала с одним из этих указателей.

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

Месяц спустя проблема с зависанием исчезла – по крайней мере с точки зрения профсоюза грузоперевозчиков. Время от времени один из их терминалов приостанавливался на полсекунды, но с базовой скоростью передачи 30 символов в секунду никто этого не замечал.

Но почему происходила десинхронизация счетчиков? Мне было 19, и я был полон решимости разобраться.

Автором кода супервизора был Ричард, уехавший на учебу в колледж. Никто из нас толком не разбирался в супервизоре, потому что Ричард относился к своему созданию очень ревниво. Код принадлежал ему, и нам было не положено разбираться в нем. Но теперь Ричарда не было, поэтому я нашел листинг толщиной в несколько дюймов и начал просматривать его страницу за страницей.

Циклические буферы в этой системе были обычными структурами данных FIFO, то есть очередями. Прикладные программы заносили символы с одного конца очереди, пока она не заполнялась. Обработчики прерываний извлекали символы с другого конца очереди, когда принтер был готов принять их. Если в очереди не оставалось символов, принтер останавливался. Из-за ошибки приложения считали, что очередь заполнена, а обработчики прерываний – что она пуста. Обработчики прерываний выполнялись в другом «программном потоке», отдельно от остального кода. Таким образом, счетчики и переменные, доступные для обоих обработчиков и остального кода, должны быть защищены от параллельного обновления. В нашем случае это означало, что перед выполнением любого кода, работавшего с этими тремя переменными, необходимо было запретить прерывания. К тому моменту, когда я сел за код, мне уже стало ясно: нужно искать участок кода, который работает с переменными без предварительного запрета прерываний.

Конечно, сейчас появилось множество мощных инструментов для поиска всех мест изменения переменных в программе. За считанные секунды вы найдете все строки кода, которые работают с переменными. За минуты можно будет определить, где именно автор забыл запретить прерывания. Однако наша история происходила в 1972 году, и у меня таких инструментов не было. Были только мои глаза.

Я просмотрел каждую страницу кода в поисках переменных. К сожалению, переменные использовались везде – почти на каждой странице программа обращалась к ним тем или иным образом. При многих обращениях прерывания не запрещались – они ограничивались чтением, а следовательно, были безвредными. Вдобавок в этом конкретном ассемблере было невозможно проверить, доступна ли переменная только для чтения, без анализа логики кода. Каждое чтение переменной могло сопровождаться ее обновлением. И если при этом прерывания не были запрещены, содержимое переменных могло быть легко испорчено.

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

Я занялся вычислениями. Уязвимость существовала на протяжении двух микросекунд. В системе дюжина терминалов передавала данные на скорости 30 символов в секунду, так что прерывания происходили каждые 3 микросекунды или около того. С учетом размера супервизора и тактовой частоты процессора зависания от этой уязвимости должны были происходить с частотой примерно 1–2 раза в день. Есть!

Конечно, я исправил ошибку, но у меня не хватило смелости отключить автоматический запуск проверки и исправления счетчиков. До сих пор не уверен в том, что в системе не было другой «дыры».

Поделитесь на страничке

Следующая глава >

Похожие главы из других книг

2.2.11. Отладка CGI

Из книги Интернет решения от доктора Боба автора Сворт Боб

2.2.11. Отладка CGI Страницу HTML с результатом, сгенерированную по запросу мы модем увидеть выполнив CGI приложение. Для этого требуется (персональный) Web сервер. По этому я написал небольшую программу отладки, используя Delphi 2.01 и NetManage HTML


2. Отладка и трассировка.

Из книги Идиомы и стили С++ автора Makhmutov Albert

2. Отладка и трассировка. Ну это совсем банально. Выносим определение операторов за определение класса и ставим там точку останова. Чтобы не тормозило в релиз версии, окружаем слово inline ифдефами.template ‹class T›#ifndef DEBUGinline#endifSmartPointer‹T›::operator T*() { return tObj;}template ‹class T›#ifndef


8.4. Отладка

Из книги Программирование на языке Пролог для искусственного интеллекта автора Братко Иван

8.4. Отладка Когда программа не делает того, чего от нее ждут, главной проблемой становится отыскание ошибки (или ошибок). Всегда легче найти ошибку в какой-нибудь части программы (или в отдельном модуле), чем во всей программе. Поэтому следует придерживаться следующего


16.4. Отладка termios

Из книги Разработка приложений в среде Linux. Второе издание автора Джонсон Майкл К.


4-й шаг. Отладка

Из книги VBA для чайников автора Каммингс Стив

4-й шаг. Отладка По мере усложнения программ вероятность появления ошибок в работе (ошибок выполнения) растет экспоненциально. После обнаружения такой ошибки главной задачей становится выявление причины ошибки и устранение проблемы. Одним словом, это отладка.В небольших


22.1. Ошибки и отладка

Из книги Linux: Полное руководство автора Колисниченко Денис Николаевич

22.1. Ошибки и отладка Самыми страшными являются не синтаксические, а так называемые логические ошибки. Ваша программа может содержать хоть сотню мелких синтаксических ошибок — там не так функцию написали, там забыли указать параметр, а где-то пропустили точку с запятой.


Тестирование и отладка

Из книги Фундаментальные алгоритмы и структуры данных в Delphi автора Бакнелл Джулиан М.

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


Отладка

Из книги Программирование для карманных компьютеров автора Волков Владимир Борисович

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


Отладка приложений в eVB

Из книги Linux программирование в примерах автора Роббинс Арнольд

Отладка приложений в eVB Отладка приложений в eVB довольно проста. После нажатия кнопки режим отладки включается автоматически. В зависимости от того, какое устройство было выбрано в списке Devices, отладка происходит на эмуляторе или на подключенном к настольному компьютеру


Глава 15 Отладка

Из книги Программирование для Linux. Профессиональный подход автора Митчелл Марк

Глава 15 Отладка Имеется множество правил, начиная с логики программы и расположения данных, через организацию и расположение кода и кончая реализацией, которые могут минимизировать ошибки и проблемы. Мы рекомендуем вам изучить их; найдите хорошие книги по


5.1.7. Отладка

Из книги Разработка ядра Linux автора Лав Роберт

5.1.7. Отладка Команда ipcs выдает информацию о взаимодействии процессов, включая сведения о совместно используемых сегментах (для этого следует задать флаг -m). Например, в показанном ниже случае сообщается о том, что используется один такой сегмент, с номером 1627649:% ipcs -m--------


5.2.4. Отладка семафоров

Из книги Использование NuMega DriverStudio для написания WDM-драйверов автора Тарво Александр

5.2.4. Отладка семафоров С помощью команды ipcs -s можно получить информацию о существующих группах семафоров. Команда ipcrm sem позволяет удалить заданную группу, например:% ipcrm sem


Глава 18 Отладка

Из книги Идеальный программист. Как стать профессионалом разработки ПО автора Мартин Роберт С.

Глава 18 Отладка Один из самых существенных факторов, который отличает разработку ядра от разработки пользовательских приложений, — это сложность отладки. Отлаживать код ядра сложно, но крайней мере по сравнению с кодом пространства пользователя. Еще больше усугубляет


2.6 Отладка драйверов

Из книги автора

2.6 Отладка драйверов Разговор о драйверах был бы неполным, если не упомянуть об отладке драйверов. Т.к. драйвера работают в нулевом кольце защиты процессора со всеми вытекающими последствиями, то обыкновенные отладчики пользовательских приложений не пригодны для


Отладка

Из книги автора

Отладка Один из худших сеансов отладки за всю мою карьеру случился в 1972 году. Терминалы, подключенные к бухгалтерской системе профсоюза грузоперевозчиков, зависали один-два раза в день. Сознательно воспроизвести ошибку было невозможно. Ошибка не отдавала предпочтений