Delphi World - это проект, являющийся сборником статей и малодокументированных возможностей  по программированию в среде Delphi. Здесь вы найдёте работы по следующим категориям: delphi, delfi, borland, bds, дельфи, делфи, дэльфи, дэлфи, programming, example, программирование, исходные коды, code, исходники, source, sources, сорцы, сорсы, soft, programs, программы, and, how, delphiworld, базы данных, графика, игры, интернет, сети, компоненты, классы, мультимедиа, ос, железо, программа, интерфейс, рабочий стол, синтаксис, технологии, файловая система...
Синий экран при исключениях FPU в Win9X

Оформил: DeeCo

Автор: Alexander Petruhiv

Условия возникновения бага - системная плата с VIA694/694T/KT133/KT133A, ОС Win95/98/Me. Под Win XP баг не проявляется.

Следующий код вызывает "синий экран" с исключением 0E. На нормально работающей машине просто напечатается 64К раз строка Trapped.

program extest;
{$APPTYPE CONSOLE}
uses SysUtils;
{$O-}
var
  i: integer;
  a, Res: Double;
begin
  a := 0;
  for i := 0 to 65535 do
  try
    Res := i / a;
  except
    writeln('Trapped');
  end;
end.

ТИПОВЫЕ РЕШЕНИЯ.
  1. Отключить сопроцессор. Панель управления->Свойства системы->Устройства->Системные устройства->Сопроцессор->Свойства->Настройка. Установить переключатель в положение Не использовать. При этом возможна некорректная работа других программ и устройств, например, принтеры HP Deskjet могут перестать печать в цвете.
  2. Замена материнской платы.
  3. Отключение генерации прерываний от FPU и выдача исключения вручную.
    program extest;
    {$APPTYPE CONSOLE}
    uses SysUtils;
    {$O-}
    
    // Функция проверки на бесконечность и нечисловое значение -
    // неоптимизирована, только для примера
    
    function InfNan(Value: double): double;
    begin
      if (FloatToStr(Value) = 'INF') or (FloatToStr(Value) = 'NAN') then
        raise EmathError.Create('');
      Result := Value;
    end;
    
    var
      i: integer;
      a, Res: Double;
    begin
      a := 0;
      Set8087CW($133F); // запретить прерывания от сопроцессора
      for i := 0 to 65535 do
      try
        Res := InfNan(i / a);
      except
        writeln('Trapped');
      end;
    end.
КОММЕНТАРИЙ:

Предложенный тест проходит так, как описано, на материнской плате с чипсетом VIA KT266 (CPU Athlon 1000): под Win98SE система трапается с синим экраном и исключением 0E, а под Win2000 сбоев не наблюдается. Поступали сообщения об аналогичной проблеме в связке Win98+K7/K6/K5. Данный материал свидетельствует о том, что и с процессорами Intel такое бывает (чипсеты VIA694/694T используются в материнских платах для Celeron и P3, а KT133/KT133A - для K7 Athlon и Duron).

Очевидно, список чипсетов может быть еще расширен. Одно общее обстоятельство сохраняется - ОС серии Win9X. Поэтому этот "камень" отнесен к категории СИСТЕМА, хотя, на первый взгляд, он просится в HARDWARE.

Как минимум, еще одно радикальное решение можно предложить - использовать Windows линии NT.

Проект Delphi World © Выпуск 2002 - 2004
Автор проекта: ___Nikolay