Как иногда пишутся программы
От: DarkMaster Украина http://www.bdslib.at.ua
Дата: 22.12.09 09:40
Оценка: 4 (1) -1
Привет всем.

Несколько дней назад попросили разобраться в коде некой программы (программа куплена с исходниками, даже есть некоторая поддержка со стороны разработчиков). Симптомы — запускаем программу, закрываем. ГУИ уходит, а вот программа остается висеть в памяти. И каждый новый запуск создает очередную копию, которая только из списка задач убивается .

Беру исходники, ProcessExplorer, компилирую, запускаю на тестовой системе — ОК. Закрываю. Запускаю еще раз — в ProcessExplorer — 2 копии программы. Еще раз запускаю — 3 копии.

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

Procedure FreeFrame(AFrame:TFrame);
begin
  if Assigned(AFrame) then
    try
     FreeAndNil(AFrame)
    except end;           // <- фокус первый - тут всегда все тихо!
end;


Ладно, открываю проблемный фрейм и пробую закрыть — AV! Еще одна попытка — "Privileged instruction bla-bla". Интересно? Обычно AV он и в Африке AV — а тут без каких либо правок — 2 разных эксепшена + Call stack указывает в небо. Идем дальше — анализируем деструкторы фреймов — ВСЕ ПРАВИЛЬНО . Все действительно корректно и должно разрушаться нормально. 2 часа дебага — и ничего — все корректно разрушается, но при закрытии фрейма всегда AV. И тут (в 2 часа ночи!) потянуло меня посмотреть, каким же образом фрейм этот создается...
Код был примерно такой:

 case AFrameType of
   fTypeOne :  Frame:=TOneFrame.Create(...);
   fTypeTwo :  Frame:=TTwoFrame.Create(...);
   .....
   else : Frame:=TBaseTypeFrame.Create(...) ;  // <- фокус второй - а давай-те хоть что-нить создадим, а?
 end;


и далее:

 case AFrameType of
   ......
   fTypeNNN : TNNNFrame(Frame).SubFrame:=TSubFrame.Create(...);  // уже догадались? Тут псевдокод, в реальном проекте тут разные свойства выставлялись.
   ...... 
 end;


Так вот, разработчики в первом case (создания фреймов) пропустили один из fTypeХХХХ и создали какой-то свой базовый фрейм. СПАСИБО! Ну кто мешал в nil выставить? Во втором case они этот fTypeXXXX не забыли и благодаря приведению типов смогли угнездить туда (ага, именно куда-то туда — где-то рядышком) еще один фрейм, который нормально работал. До попытки закрытия При закрытии деструктор лез непонятно куда и пытался что-то разрушить. Ну а благодаря некоторым манипуляциям вроде первой приведенной процедуры программа просто не могла нормально завершить свою работу.

Вывод — если уж пользуетесь приведением типов — делайте это в презервативе...

P.S. Процедуру создания фреймов я исправил, разработчиков известил (ну нет у меня времени выискивать все их пасхальные яйца). Жду новых оригинальных решений.
WBR, Dmitry Beloshistov AKA [-=BDS=-]
Re[4]: Как иногда пишутся программы
От: DarkMaster Украина http://www.bdslib.at.ua
Дата: 22.12.09 13:57
Оценка: 1 (1)
Здравствуйте, hattab, Вы писали:

H>Здравствуйте, DarkMaster, Вы писали:


DM>> Я не против try...except. Я против "глухого" срабатывания. Если произошло исключение — будь добр сообщить пользователю или по крайней мере запиши в лог, если исключение не ожидаемое. (Как меня бесило в свое время "Connection closed gracefully" в Indy — кто б знал!).


H>Ну, исключения не всегда являются ошибками. А по Инди есть книжица (Глубины Indy), где объясняется почему именно так, а не иначе


Ну я же сказал — "....если не являются ожидаемыми". Обьясняется, согласен. Но бесит
WBR, Dmitry Beloshistov AKA [-=BDS=-]
Re: Как иногда пишутся программы
От: Nonmanual Worker  
Дата: 22.12.09 12:11
Оценка:
Здравствуйте, DarkMaster, Вы писали:

У одного известного российского разработчика компонентов создания отчетов, код внутри почти всех деструкторов был заключен в try..except
Re[2]: Как иногда пишутся программы
От: DarkMaster Украина http://www.bdslib.at.ua
Дата: 22.12.09 12:37
Оценка:
Здравствуйте, Nonmanual Worker, Вы писали:

NW>У одного известного российского разработчика компонентов создания отчетов, код внутри почти всех деструкторов был заключен в try..except


Не у Цыганенко ли?

Я не против try...except. Я против "глухого" срабатывания. Если произошло исключение — будь добр сообщить пользователю или по крайней мере запиши в лог, если исключение не ожидаемое. (Как меня бесило в свое время "Connection closed gracefully" в Indy — кто б знал!).

Но основной "выстрел в ногу" в том, что путем приведения типов и неправильном обращении с такими вот сущностями можно получить трудноуловимый баг.
WBR, Dmitry Beloshistov AKA [-=BDS=-]
Re[3]: Как иногда пишутся программы
От: hattab  
Дата: 22.12.09 13:24
Оценка:
Здравствуйте, DarkMaster, Вы писали:

DM> Я не против try...except. Я против "глухого" срабатывания. Если произошло исключение — будь добр сообщить пользователю или по крайней мере запиши в лог, если исключение не ожидаемое. (Как меня бесило в свое время "Connection closed gracefully" в Indy — кто б знал!).


Ну, исключения не всегда являются ошибками. А по Инди есть книжица (Глубины Indy), где объясняется почему именно так, а не иначе
avalon 1.0rc2 rev 272
Re: Как иногда пишутся программы
От: shvonder Россия  
Дата: 13.01.10 08:58
Оценка:
Здравствуйте, DarkMaster, Вы писали:
[..]
Улыбнуло
А я познакомился с таким вариантом дизайна: из математической (!) процедуры программно нажимаются 3-и невидимые кнопки на форме, в обработчиках которых чё-то делается
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.