Трудно обнаружить неопределенное поведение (или ошибку)

#c #debugging #undefined-behavior #cinder

#c #отладка #неопределенное поведение #cinder

Вопрос:

Я делаю базовое приложение cinder в Visual Studio. Это генерация частиц (в общих чертах следуя онлайн-руководству Hello Cinder. В режиме отладки это всегда работает. Однако в конфигурации выпуска иногда не генерируется никаких частиц.

Я предполагаю, что где-то есть UB, проблема в том, что его действительно трудно обнаружить. Небольшие, казалось бы, несвязанные изменения могут вызвать или отменить это.

Например, изменение функции draw :

 spatial_.speed_  = 0.1f * ci::Vec2f(cos(noise * 15.0f), sin(noise * 15.0f));
//                ^^^^^
//                this value
  

любое постоянное значение, отличное от 1.0f, или отсутствие постоянного значения не приведет к созданию частицы. Как изменение в функции draw может повлиять на код в функции update (где я генерирую частицы). Я знаю, что они вообще не генерируются, потому что я показываю количество частиц.

Все виды подобных изменений по всей программе вызывают это (например, изменение констант, изменение типов параметров со значения на ссылку, добавление или удаление строки, которая выводится в console()).

Я не хочу, чтобы вы, ребята, отлаживали мой код, вот почему я не помещал код здесь.
Я просто не понимаю, как с этим справиться. Мой вопрос в том, как мне приступить к диагностике ошибки? Какие у меня есть варианты, какие шаги я должен предпринять отсюда?

Проблемы, с которыми я сталкиваюсь:

  • Я понятия не имею, где ошибка во всем коде.
  • В режиме отладки все работает нормально
  • Я не могу отлаживать в режиме выпуска ( debugging information for ***.exe cannot be found or does not match. Binary was not build with debug information ), и любые точки останова отображаются в графическом интерфейсе с помощью всплывающей подсказки the breakpoint will not be currently hit (no symbols have been loaded for this document)
  • Я не могу отлаживать вывод на печать, потому что добавление кода для отображения вывода заставит программу работать. (Насколько это иронично?)
  • В режиме выпуска, даже если я заставлю его работать (методом проб и ошибок, добавлением / удалением строк), если я не определю проблему, нечего сказать, что изменение чего-либо в другом месте снова нарушит код.

Обновить:

  • CppCheck сообщает об отсутствии проблем. Я вручную дважды проверил наличие неинициализированных членов / переменных.
  • Я пытался изолировать эту вещь. Проблема в том, что ЛЮБОЕ изменение, которое я делаю, приведет к генерации частиц. Если я изменю какой-либо код в draw функции, будут сгенерированы частицы. Если я удалю код для размера частиц, частицы будут сгенерированы. Если я удалю код для движения, частицы будут сгенерированы. Если я удалю код для рисования частиц, частицы будут сгенерированы. Если я удалю код для начальной позиции частиц, частицы будут сгенерированы, если я удалю код, который удаляет мертвые частицы, частицы будут сгенерированы. Единственное, что, как я обнаружил, поддерживает ошибку, — это если я изменяю настройки fps, так что да, я знаю, что установка fps не вызывает проблемы, так что ура.

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

1. Рассматривали ли вы модульные тесты?

2. @KerrekSB Я никогда не работал с модульными тестами (я студент). Как это работает?

3. Шаг 1 — изолировать поведение в небольшой полной программе

4. @bolov: Купите книгу или пять по этому предмету, изучите фреймворк тестирования или три и начните писать некоторые проекты на основе тестирования.

5. Попробуйте статический анализатор кода C , такой как Cppcheck — он может указать вам на возможные причины UB, такие как использование неинициализированных переменных, игнорирование кодов возврата функции и т.д.