OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Четверг, 28 Март, 2024 19:25

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 2 ] 
Автор Сообщение
 Заголовок сообщения: GC crash
СообщениеДобавлено: Четверг, 12 Ноябрь, 2009 23:10 
Аватара пользователя

Зарегистрирован: Вторник, 19 Сентябрь, 2006 21:54
Сообщения: 2449
Откуда: Россия, Томск
Вчера отловил неприятный баг. Система рушилась при сборке мусора: NIL pointer dereference. С трудом нашли рецепт воспроизведения, потом я дихотомически локализовал сбой путём добавления oberonRTS.Collect и отладочного вывода в файл. Далее пришлось зарыться в дизассемблер-отладчик. (Огромное спасибо компании Data Rescue за бесплатную версию IDA Pro!) Это с моим-то знанием ассемблера... плохим.

Проблема, слава богу, оказалась не в рантайме XDS, а в нашем коде. Точнее, в неосторожном обращении с низкоуровневыми средствами. Есть такая процедура, которая в произвольный буфер памяти складывает данные:
Код:
ItemToBuffer (VAR buff: ARRAY OF SYSTEM.BYTE; ...);
(* Помещаем данные в buff либо читаем из buff, в зависимости от прочих параметров процедуры. *)
А в другом модуле она используется:
Код:
VAR mem: Common.Buffer;
BEGIN
   NEW (mem, GetSize (item));
   ...
   ItemToBuffer (mem, ...);
Код, естественно, сильно упрощён. На самом деле mem - это поле объекта, объявление его далеко и не видно, а тип Common.Buffer - ещё дальше, в другом модуле. И тип этот такой: POINTER TO ARRAY OF SYSTEM.BYTE. ItemToBuffer - тоже метод объекта и находится в третьем модуле. То, что вся эта информация далеко разнесена по разным местам, делает проблему неочевидной. А то, что низкоуровневый формальный параметр типа ARRAY OF SYSTEM.BYTE совместим с ЛЮБЫМ фактическим параметром, заставляет компилятор пропускать нашу ошибку и считать, что POINTER TO ARRAY OF SYSTEM.BYTE и просто ARRAY OF SYSTEM.BYTE - это практически одно и то же. Даже предупреждения не было.

А правильно было написать вот так:
Код:
ItemToBuffer (mem^, ...);
Как видите, ошибка всего в один символ, а в результате младшие два байта указателя затирались нулями, и сборщик мусора ломался в какой-то случайный момент времени после порчи памяти.

svn blame показал, что с момента внесения ошибки до момента устранения прошло... Готовы?.. 1 год и 9 месяцев. Это ошибка в библиотеке общего назначения, используемой несколькими коммерческими приложениями. 21 месяц подряд приложения закрывались с ошибкой в случайный момент времени без видимых причин, и никак невозможно было связать поломку ни с действия пользователя, ни с недавними изменениями в приложениях или библиотеке.

Отсюда несколько выводов:
  1. Низкоуровневые средства нельзя размазывать по системе и использовать без чёткого обозначения красными флажками. В идеале, тонкая прослойка между кодом низкого и высокого уровня должна быть перекрыта мощным тестовым набором.
  2. Сборку мусора необходимо проводить регулярно - например, в idle loop - хотя бы для проверки целостности памяти. Хорошее время для очистки памяти - обработчик закрытия окна, когда внимание пользователя отвлечено переключением к очередной задаче. В случае сбоя пользователь не сможет сказать, что именно он сделал, но наверняка вспомнит окно, с которым только что закончил работать.
  3. Даже на такое низкоуровневое средство компилятор должен был бы ругаться. Шутка ли - спутать ARRAY и POINTER TO ARRAY! Указатель вообще не должен в неявном виде приводиться к неуказательному типу, это же прямой путь к адресной арифметике. Надо привести - есть SYSTEM.VAL, SYSTEM.ADR, и прочие прелести модуля SYSTEM.
  4. Дизассемблеры нужны не только кракерам, но и высокоуровневым программистам.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: GC crash
СообщениеДобавлено: Пятница, 13 Ноябрь, 2009 00:14 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9459
Откуда: Россия, Орёл
Есть вот такое средство борьбы с "размазыванием SYSTEM по системе": viewtopic.php?f=2&t=2006


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 2 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 9


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Вся информация, размещаемая участниками на конференции (тексты сообщений, вложения и пр.) © 2005-2024, участники конференции «OberonCore», если специально не оговорено иное.
Администрация не несет ответственности за мнения, стиль и достоверность высказываний участников, равно как и за безопасность материалов, предоставляемых участниками во вложениях.
Без разрешения участников и ссылки на конференцию «OberonCore» любое воспроизведение и/или копирование высказываний полностью и/или по частям запрещено.
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB