Читаем Кодеры за работой. Размышления о ремесле программиста полностью

Сейбел: То есть память портилась из-за аппаратных ошибок, а не из-за вышедшего из-под контроля указателя?

Томпсон: Мог быть указатель. Могло быть оборудование. Или и то, и другое. Та ошибка, которая мне сейчас вспомнилась как один из худших примеров, случилась на PDP-11. Там не было блока умножения, но его можно было докупить отдельно и подключить как периферию ввода/вывода. Сохраняешь числитель и знаменатель и запускаешь. Проходит цикл ожидания, затем выдается ответ — частное и остаток. И это было сделано под PDP-11 без управления памятью, а потом к нам пришло первое экспериментальное оборудование для PDP-11 с управлением памятью, и в результате блок умножения конфликтовал с управлением памятью.

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

Сейбел: Как же в итоге удалось ее отследить?

Томпсон: Я написал программу, которая должна была поставить мировой рекорд по нахождению знаков числа е. Предыдущие мировые рекорды были ограничены не вычислениями — количеством циклов в секунду, — а вводом/выводом. Я придумал новый алгоритм, узким местом которого были вычисления (ввод/вывод был тривиальным). Он был феерически тяжелым в отношении умножения и деления. И мы заметили, что машина каждый раз буквально обрушивалась, когда я запускал на ней эту свою программу. А потом и установили связь.

Сейбел: И это дало вам возможность понять, что проблема в умножителе. Вы сразу же нашли причину?

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

Сейбел: К счастью, сейчас оборудование так не сыплется.

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

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

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

Сейбел: Сегодня некоторые говорят: «Да, конечно, у ассемблера больше всего шансов повредить память из-за программных ошибок, но и Си склонен к этому больше, чем некоторые другие языки». Можно сделать так, что указатели будут указывать черт знает куда, и получится выход за границу массива. Вы не считаете, что это проблема?

Томпсон: Нет, ее можно обойти языковыми оборотами. Некоторые пишут хрупкий код, а некоторые — очень крепкий структурно, и тут все зависит от человека. Думаю, хрупкий код можно написать на любом языке. Я определяю хрупкий код так: допустим, требуется добавить функциональность, так вот в хорошем коде ее нужно добавить только в одно место, а в хрупком придется затронуть сразу десять мест.

Сейбел: Если появляется брешь в безопасности из-за переполнения буфера, то что вы можете ответить на критику Си и C++, где утверждается, что они частично за это ответственны, что многих проблем можно было бы избежать, если использовать язык, который проверяет границы массивов или в котором есть сборка мусора?

Перейти на страницу:

Похожие книги

Адмирал Советского Союза
Адмирал Советского Союза

Николай Герасимович Кузнецов – адмирал Флота Советского Союза, один из тех, кому мы обязаны победой в Великой Отечественной войне. В 1939 г., по личному указанию Сталина, 34-летний Кузнецов был назначен народным комиссаром ВМФ СССР. Во время войны он входил в Ставку Верховного Главнокомандования, оперативно и энергично руководил флотом. За свои выдающиеся заслуги Н.Г. Кузнецов получил высшее воинское звание на флоте и стал Героем Советского Союза.В своей книге Н.Г. Кузнецов рассказывает о своем боевом пути начиная от Гражданской войны в Испании до окончательного разгрома гитлеровской Германии и поражения милитаристской Японии. Оборона Ханко, Либавы, Таллина, Одессы, Севастополя, Москвы, Ленинграда, Сталинграда, крупнейшие операции флотов на Севере, Балтике и Черном море – все это есть в книге легендарного советского адмирала. Кроме того, он вспоминает о своих встречах с высшими государственными, партийными и военными руководителями СССР, рассказывает о методах и стиле работы И.В. Сталина, Г.К. Жукова и многих других известных деятелей своего времени.Воспоминания впервые выходят в полном виде, ранее они никогда не издавались под одной обложкой.

Николай Герасимович Кузнецов

Биографии и Мемуары
100 великих гениев
100 великих гениев

Существует много определений гениальности. Например, Ньютон полагал, что гениальность – это терпение мысли, сосредоточенной в известном направлении. Гёте считал, что отличительная черта гениальности – умение духа распознать, что ему на пользу. Кант говорил, что гениальность – это талант изобретения того, чему нельзя научиться. То есть гению дано открыть нечто неведомое. Автор книги Р.К. Баландин попытался дать свое определение гениальности и составить свой рассказ о наиболее прославленных гениях человечества.Принцип классификации в книге простой – персоналии располагаются по роду занятий (особо выделены универсальные гении). Автор рассматривает достижения великих созидателей, прежде всего, в сфере религии, философии, искусства, литературы и науки, то есть в тех областях духа, где наиболее полно проявились их творческие способности. Раздел «Неведомый гений» призван показать, как много замечательных творцов остаются безымянными и как мало нам известно о них.

Рудольф Константинович Баландин

Биографии и Мемуары
100 великих интриг
100 великих интриг

Нередко политические интриги становятся главными двигателями истории. Заговоры, покушения, провокации, аресты, казни, бунты и военные перевороты – все эти события могут составлять только часть одной, хитро спланированной, интриги, начинавшейся с короткой записки, вовремя произнесенной фразы или многозначительного молчания во время важной беседы царствующих особ и закончившейся грандиозным сломом целой эпохи.Суд над Сократом, заговор Катилины, Цезарь и Клеопатра, интриги Мессалины, мрачная слава Старца Горы, заговор Пацци, Варфоломеевская ночь, убийство Валленштейна, таинственная смерть Людвига Баварского, загадки Нюрнбергского процесса… Об этом и многом другом рассказывает очередная книга серии.

Виктор Николаевич Еремин

Биографии и Мемуары / История / Энциклопедии / Образование и наука / Словари и Энциклопедии