среда, 2 декабря 2009 г.

Про баги: падать или не падать

Здравствуй, дорогой и горячо любимый Access Violation Елена Сагалаева начала серию статей “Искусство отладки” и даже уже опубликован первый пост “Как предупредить появление багов”. Тема конечно же глубинная. Ре-хех, чуется да будет драка… Да чего уж там, судя по комментариям “гнать из команды”, “не пишем код и не будет багов” – драка уже началась! Ну, как говорится: “amen. понеслася!”. Но посты прелюбопытнейшие, даже порой заглядываю перечитать и поразмышлять. Чего уж тут!?! Достали меня уже в ноль анализы засранных бизнес-требований (сами не знают, чего хотят), бесконечные флеймы в форуме технической поддержки, и все прочие маркетинги-и-иже-с-ними. Давайте-ка лучше маленько подебажим :)

Хех, баги есть, были и всегда будут. А кончатся? Не пропадем – съездим к трем вокзалам и возьмем наплодим новых! Когда баги вползли по невнимательности, ну или по банальной опечатке (такое бывает: начинаю уже тихо материться на автозавершение кода (autocompletion), о  сколько багов оно наплодило в моем коде) - с этим более менее понятно как бороться: code review, нормальные комментарии, assertions где только возможно. В общем, все понятно: баги подобного рода нужно максимально переловить на стадии альфа (бета) релиза.

Но ведь бывает и иначе: “Ты суслика видишь? Нет… А он есть!”. То бишь, ну неоткуда багу взяться, хоть тресни неоткуда и всё тут! Но он есть. И хорошо, если четко диагностируемый и постоянный, а если мигающий да зависящий от конфигурации!?! Imho, в альфа-версиях лучше уж пусть софтина рухнет, грохнется с самым поганым Access Violation, погребя под собою весь процесс вместе с пользовательскими данными заодно. Ну и ладно, зато проблема станет явной.

Буквально последние дни доделываю новую фичу в Aml Pages. Фича весьма неслабая. Мало того, что вовсю используются виртуальные списки (SysListView), когда данные в одном месте, а визуализация их происходит по мере прокручивания списка пользователем. Дык там еще и сами данные выдергиваются многопоточно (а юзер – нет, ну вот зараза какая – старается еще и изменить данные уже в третьем треде). Лично по мне, пусть вся Aml Pages рухнет с треском в релизной сборке, если где-то вдруг у нас порою закрался баг. Всё лучше, чем кряхтя и поднатужившись продолжит выполнение, непонятно в какой винегрет превращая пользовательские данные.

Нет, нет! Никто не собирается вывалить все эти баги на пользователя. Ни в коем случае. В коде уже очень многое предусмотрено: и контроль индексов, и корректная обработка висячих указателей, и проверка на deadlock при многопоточной обработке. Но все это будет задействовано только в первом публичном бета-релизе. В альфа-версии фиг – все максимально сбое-вероятно, пусть уж лучше мой код покажет свое истинное нутро.

Всё просто: проблема не в баге  - проблема в том, откуда он вообще взялся. Если написано, что индекс должен быть от массива “А”, то именно для него он и должен быть, и причем валидным, а не для соседнего. А коль индекс не валидный, то вынуть по нему данные все равно не получится. Выкрутиться можно, но вот вынуть данные корректно, это фиг. В публичном релизе будет и такая страховка. Но проблема в данном случае, не в том что пытаемся вытащить данные по кривому индексу, а в том, откуда такой кривой индекс вообще взялся.

Если весь алгоритм сразу проектировался так, что даже взрыв ядреной бомбы за окном не может повредить индексы, то кривой индекс означает только одно: ядреная бомба где-то в коде. И уж пусть софтинка рухнет намертво – зато проблема станет явной, и явной именно сейчас, в стадии альфа-версии, а не в финальном релизе на машине пользователя. Сиди потом, медитируй на тему “ё-маё, что ж  я сделал, и как они пытаются это использовать”.

Свеженький пример: буквально последние полдня переписывал алгоритм для упомянутой выше фичи почти с нуля (кроме фоновых потоков по извлечению данных – с ними изначально все было вылизано). Парочка простейших приёмов и тут же обнаружил откровенные логические ошибки, но которые так запросто и не заметишь:

  1. Банальное переименование некоторых функций. Причина проста: семантически параметры некоторых функций изменились, но не изменились синтаксически. То бишь надо все эти, а желательно еще и соседние, моменты проверить. Но компилятор сам такие ляпы не поймает, т.к. ну нет никакого ляпа с его точки зрения. И что делать? Шерстить глазами? Дык не годится – человеку, и его глазам в частности, свойственно ошибаться. А коли свойственно, то ошибка допущена будет.
    Делаем просто: переименуем старую функцию, ну скажем, GetDataByIndex в нечто вроде GetDataByIndex2 и перекомпилируемся. Компилятор, ясное дело ругается на все вызовы функции по старому имени. Аккуратно просматриваем всю “ругань”, не спеша и тщательно проверяя семантику параметров. Приводим код в полную работоспособность. Ну и под конец, не грех переименовать GetDataByIndex2 во что-нибудь более говорящее, вроде GetDataByArrayIndex чтобы в будущем не путать, что за индекс.
  2. Везде где можно применяются assertions: т.е. проверяется истинность почти всего подряд: висячесть указателей, выход индексов за пределы массива, pre- и post-условия выполнения. В отладочном коде при неверности условия, будет отрабатывать отладочный код, а хоть бы и жутко “матерный” MessageBox. В релизной сборке таких проверок нет, и тем более нет этого “матерного MessageBox`а”. Но даже если что-то было и упущено, то в релизной сборке программа просто рухнет, и проблема станет явной. Чего и добивались – чтобы найти решение проблемы, о ней хотя бы нужно знать. 

Собственно всё! Уже только этих два приема сходу выловили с пяток косяков точно. Остальные ждём-с в релизной сборке – нехай падает.
Имхо, в тестовых версиях баг это благо – он повод задуматься “а с какого-такого перепуга”. Качество и надежность кода – это задача финальных версий. Но без вопроса “с какого перепуга” эта самая пресловутая надежность кода никогда не будет достигнута. Нет вопроса – не будет и ответа.

PS: в комментариях к первому посту Елены упоминал книгу Роббинса по отладке – собственно вот она на Books.ru. К сожалению, в свое время, так и не удалось найти самую первую “отладку” Роббинса. Но, у него есть еще одна любопытная книга: “Отладка Windows приложений” – тоже вещь впечатляющая, а главное и актуальная по сей день. Имхо, must have обе. Но… блин, первую отладку похоже не скоро переиздадут, а жаль – солидное чтиво – мозги на нужный лад настраивает.

PPS: стоп! А как же самый главный пост-скриптум!?! Елене отдельное СПАСИБО за интереснейший цикл статей. Так держать!

Комментариев нет:

Отправить комментарий