Хромающая диагностика

Снова в который уже раз проблема с тулсетом требует длительного выяснения, пересборки в дебаге и в результате оказывается, что там стоит гадский ассерт, который в релизной конфигурации, ессно, вырезался, а программа далее успешно зависает (ну или падает – зависит от фазы луны).
В который уже раз буду банальным – грамотная диагностика – залог успешности программы, особенно если речь идет о тулсете. Не невидимые в релизе ассерты, которые половиной программистов не ставятся вообще, а половиной – ставятся абы как, а правильная и четкая диагностика, которая с одной стороны, может защитить приложение от сбоев в какой-то его части, а с другой стороны, позволяет сразу получить понятное описание проблемы.

Как то во времена Американ Чоппера, когды мы в Крейте жили целыми месяцами, был такой случай. Я случайно оказался дома, чтобы поспать 4 законных часа, как меня телефонным звонком разбудил Стас Богданов, который спросил: ”Дима, а что такое Scene index must be zero blababla….? Никогда такого не встречал”. Мне потребовалось несколько секунд, чтобы понять, какая именно дьявольская комбинация аргументов командной строки и описаний в текстовом файле могла привести к таким последствиям, и вопрос был дистанционно и мгновенно решен. Эта строка была написана за год до описываемых событий и никогда до и никогда после этого в процессе обработки уровня не встречалась.

Не спорю, что писать логи – это долгое занятие (хотя отладка – еще более долгое). Не спорю, что далеко не все программисты в состоянии вспомнить, что за строчка была написана за год до события. Но писать циничное a = malloc(); assert(a); – это то же самое, как если бы написать a = random(); assert(a != 0.5). То есть мы ассертируем стандартное поведение функции, которое описано в справочнике.

Пример с маллоком далеко не единственный. Конкретно в данном случае срубилось необработанное CreateProcess(). Вообще я стараюсь придерживаться следующего правила: нужно ассертировать программистские ошибки. Валидные (описанные в MSDN) коды возврата функций API, предположения о формате или синтаксисе файлов, наличия файлов на диске, аргументов командной строки, нажимаемых пользователем кнопок – никакие такие действия не могут ассертироваться, они должны корректно обрабатываться и еще сохранять данные в лог, чтобы можно было разобраться, что произошло, даже в полвторого ночи.

try catch, кстати, тоже не панацея – во первых, он тоже не провоцирует писать логи (за исключением того, что м.б. “Что-то упало внутри этого блока try”, а вто вторых, им еще надо грамотно уметь воспользоваться.

  • http://www.sdl.ru TSS

    Ассерты вообще вещь в себе. Дебаг версия в 35% случаев “внутри себя” не ведет как релиз.
    try – catch вообще нужно запретить: упало – разбирайтесь почему, был ли контроль аргументов, кончилась память или ошибка в алгоритме.
    Логи вещь хорошая, но вот только нужно очень грамотно настраивать уровни протоколирования, иначе в них можно просто утонуть.

  • GLoom

    А можно подробнее про try/catch в C++? Я вернулся к С++ после 3х лет С#, поэтому тема для меня очень актуальная.

  • my.name

    если дергаешь массив указателей на функции, и одна из них бросит ексцепшен, то даже поймав его, мы нарушаем логику, ибо не дернули оставшихся указателей.

  • volodya

    Ассерты никто не отменял, если их правильно юзать. Описано, например, тут: http://codingvault.org/forum/viewtopic.php?f=4&t=12&sid=2e3c586782c2441b9dfe15a25f4de158