MyWackoSite: FatBrother/МоиКниги/OsErrata ...

Home Page | Каталог | Изменения | НовыеКомментарии | Пользователи | Регистрация | Вход:  Пароль:  
Это старая версия FatBrother/МоиКниги/OsErrata за 2006-03-22 11:34:55..

Список замеченных содержательных ошибок в первом издании книги «Введение в операционные системы»


Раздел 4.4.1 Управление памятью в Mac OS? и Win 16?

Все инвективы в адрес «ручечного» управления памятью относятся к программированию на plain C и Pascal, т.е. на языках, в которых есть понятие указателя, но при этом указатель нельзя ни во что «завернуть» (как это можно сделать в C). Действительно, в C можно спрятать «ручку» внутри класса smart pointer, который выглядит как указатель, поддерживает все те же самые операции, но делает Global Unlock? в подходящий момент. Поэтому уже при программировании на C++ проблема далеко не так остра, как при программировании на C.

В языках более высокого уровня – Smalltalk, Java, даже в Basic – понятия указателя вообще нет, и разработчик среды исполнения языка волен реализовать объектные ссылки так, как сочтет нужным. В том числе путем инкапсуляции «ручки» внутри этой ссылки.
Реальные интерпретаторы Smalltalk и современные виртуальные машины Java / C?# реализованы именно таким образом: каждая объектная ссылка представляет собой «ручку» – индекс в глобальном массиве указателей на объекты. Это позволяет перемещать объекты по памяти, не теряя ссылок на них, и реализовать такие стратегии сборки мусора, как копирующие и генерационные. В этом смысле, слова, что от «ручечного» управления памятью все отказались, просто не соответствуют действительности.

Тем не менее, критика эксплуатационных характеристик Win 16? в этом разделе полностью соответствует действительности. Во второй половине 80х, когда начинась разработка приложений для Mac OS?, язык C++ был вообще только что придуман, и до середины 90х нормальных компиляторов этого языка вообще не было. Поэтому старые приложения для Mac OS? и большинство коммерческих приложений для Win 16? разрабатывались на plain C и очень сильно страдали от ошибок работы с «ручками».

Исправлено во втором издании книги

Раздел 5.4 Разделяемые библиотеки

В книге утверждается, что в OS/2 и Win 32? разделяемые библиотеки загружаются в определенный глобальный диапазон адресов и при загрузке перемещаются для настройки на свободные адреса. Это не совсем верно.

Точнее, это безусловно верно для OS/2: в этой системе приватные сегменты EXE и DLL формата LE/LX загружаются с начала 512-мегабайтного адресного пространства, а разделяемые – с конца. При этом все DLL перемещаются. При этом перемещенный код, разумеется, считается модифицированным и при подкачке сбрасывается в swap-файл. В Win 32?, DLL формата PE имеют таблицу перемещений (т.наз. fixup). В Windows 95 эта таблица даже принудительно используется – все DLL загружаются как разделяемые и всегда загружаются в третий гигабайт адресного пространства.

Я долгое время пребывал в убеждении, что аналогичная схема загрузки используется и в линии Windows NT, с той лишь разницей, что система не отображает DLL в адреса тех процессов, которые об этом явно не просили, а начиная с версии 4.5 (Windows 2000) еще и учитывает при загрузке полное путевое имя DLL, позволяя, таким образом, загрузить несколько одноименных библиотек. Это убеждение и отражено в книге.

Действительность оказалась гораздо богаче. Кроме fixup, PE DLL имеют также «рекомендованный» адрес загрузки. Windows NT пытается загрузить DLL по этому адресу. Если это получается, код DLL оказывается разделяемым и при подкачке берется из файла DLL. Поскольку он не модифицирован, то не требуется сбрасывать его в swap-файл. Самое интересное происходит, если код не удается загрузить по рекомендованному адресу. Тогда Windows использует fixup-таблицу и перемещает код по свободному адресу, который ищет в адресном пространстве текущего процесса. Как и в OS/2, перемещенный код считается модифицированным и подкачивается из swap-файла.

Разумеется, в адресных пространствах других процессов этот диапазон адресов может оказаться занят, поэтому Windows не разделяет сегмен кода такой DLL. Никогда.

Таким образом, основная схема загрузки DLL в Windows NT похожа на схему, применяемую в архаичных юниксах с форматами a.out и COFF (кстати, формат PE и является нестандартным расширением формата COFF). Только адресное пространство для разделяемых библиотек никто не распределяет. Вообще никто. Вместо этого, загрузчик использует фиксап-таблицу для разрешения конфликтов. Разумеется, на машинах, на которых установлена сложная смесь приложений, возникает много конфликтов и производительность сильно страдает. Это еще одна причина, по которой не рекомендуется устанавливать на Windows-серверах несколько серверных приложений.

Исправлено во втором издании книги

Раздел 11.4.1 Устойчивость к сбоям питания

Архиваторы Pk ZIP? и Info Zip? действительно сохраняют каталог архива в конце файла. И, действительно, недописанный или недокачанный архив не имеет каталога и оказывается испорченным. Однако утверждение, что он испорчен безнадежно, не соответствует действительности. Информация каталога, в действительности, дублируется в теле архива – перед каждым файлом размещается метаинформация о нем с указанием имени, даты создания, длины упакованного образа и т.д. На основе этой информации архиватор может воссоздать каталог – у Info Zip? это делается запуском zip с ключом -F или -FF. Разумеется, если речь идет о недописанном архиве, последий файл в архиве будет поврежден. Эта операция осуществляется путем полного сканирования архива с проверкой контрольных сумм, поэтому работает довольно долго, но на выходе получается полноценный архив со всеми полагающимися каталогами.

Эта ошибка была допущена в определенном смысле сознательно – мне хотелось найти убедительный пример того, как нештатное завершение программы приводит к потере данных. Более удачным примером, возможно, было бы поведение MS Office – но и там, в версии Office 2003, была добавлена возможность «починки» поврежденных файлов. По видимому, удачный и в то же время общеизвестный пример найти практически невозможно, потому что все более или менее распространенные форматы файлов в той или иной степени допускают их починку после аварийного завершения программы. Форматы же файлов, которые этого не допускают (и приложения, которые этого не умеют) просто не получают распространения. Естественный отбор в действии.

Исправлено во втором издании книги

Если вы знаете (или считаете, что знаете) о каких-то других ошибках, пишите комментарии к этой странице.
 
Файлов нет. [Показать файлы/форму]
Много комментариев (2). [Показать комментарии/форму]