Как я могу найти редкую ошибку, которая возникает только в сборках релиза? - PullRequest
1 голос
/ 15 июля 2010

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

"Ни один символ не загружен ни для одного фрейма стека вызовов. Исходный код не может быть отображен"

Этоделает довольно сложно найти причину сбоев.Я использую настройки сборки выпуска по умолчанию для Visual Studio 2008, в которых для формата отладочной информации задано значение «База данных программ» (/Zi)'.

У вас есть какие-либо советы, которые могут помочь мне найти ошибку?Например, могу ли я изменить некоторые параметры в своих проектах, чтобы сбой все еще мог происходить, но получить более значимую информацию в отладчике?

Обновление: Проблема была в очень редко встречающейся логической ошибкеэто само по себе не должно вызывать сбой, но, очевидно, вызвало сбой в другом месте.Решение логической ошибки решило сбойное поведение.

Всем, кто пришел сюда в поисках решения аналогичной проблемы: удачи, вам предстоит тяжелая поездка.В конечном итоге мне удалось определить причину проблемы: добавить в код множество проверок границ (которые я мог включить / отключить с помощью директив препроцессора) и скомпилировать для linux и запустить с помощью gdb / valgrind.

Ответы [ 6 ]

5 голосов
/ 15 июля 2010

Если код падает после применения оптимизации (как в выпуске по умолчанию), наиболее вероятно, что ваш код каким-то образом имеет недостатки и зависит от неопределенного поведения, которое изменяется между выпуском и отладочной сборкой.

Попробуйте отключить оптимизацию в сборке выпуска, чтобы посмотреть, исчезнет ли проблема (или включите ее в сборке отладки, чтобы увидеть, если она возникает) Если это произойдет, вы все равно должны стремиться найти и исправить ошибку, но вы по крайней мере будете знать, что ищете неопределенное поведение.

Установите максимальный уровень предупреждений компилятора (/ W4) и предупреждения как ошибки (/ Wx) и исправьте все предупреждения (а не просто бросая все в поле зрения - подумайте об этом!). Когда применяется оптимизация, вы можете получить предупреждения, которых не было в отладочной сборке из-за более глубокого анализа кода, который выполняется - это полезный статический анализ.

Вы можете, если хотите, включить отладку в оптимизированной сборке, но маловероятно, что вы сможете следить за происходящим, так как оптимизатор может переупорядочивать код и удалять код и переменные.

5 голосов
/ 15 июля 2010

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

Во-вторых, используйтеМодули просматривают во время отладки, чтобы убедиться, что символы загружены.

Самый простой способ получить символы - это поместить файлы .pdb в то же место, что и сборки.

Извлечь Блог Джона Роббинса для многих других деталей этого *. 1010 *

4 голосов
/ 15 июля 2010

Звучит так, будто кадр стека сорван.Тривиально сделать с переполнением буфера, просто скопируйте большую строку, например, в маленький символ [].Это стирает обратный адрес.Код просто продолжает работать до тех пор, пока не вернется, а затем бомбит, когда он выбрасывает неверный адрес из стека.Или хуже, если адрес окажется действительным.

Отладчик не может отобразить ничего значащего, поскольку он не может пройтись по стеку, чтобы показать вам, как код попал в место сбоя.Фактическое место крушения ничего вам не говорит.

Туф как гвозди для отладки.Вы должны сделать его воспроизводимым, и вам нужно либо перейти, либо отследить, чтобы найти последнюю заведомо исправную функцию.Тот, который вызывает сбой после выхода из него, тот, с ошибкой.Вы можете увидеть оператор, который наносит ущерб, стек вызовов отладчика неожиданно становится кататоническим.Если вы не можете получить последовательное воспроизведение, то все, что осталось, - это тщательный анализ кода.Вы можете оправдать время, назвав это «проверкой безопасности».Удачи с этим.

4 голосов
/ 15 июля 2010

Несколько причин, по которым отладочная сборка может не позволить дефекту выразить себя:

  • Некоторые конфигурации отладки инициализируют все переменные.
  • Отладка выделения памяти и освобождения может быть более щадящим злоупотреблением указателем.
  • Сборка отладки может выполняться с другой скоростью, маскируя состояние гонки.

Поскольку вы используете C ++, вы можете рассмотреть возможность использования инструмента статического анализа, такого как valgrind, чтобы указать на возможные неинициализированные данные и неправильное обращение с указателем.

Условия гонки можно отследить, добавив вывод журнала с отметками времени. Сначала вы должны определить, где в вашем «большом решении» проблема возникает, наблюдая за тем, что произошло непосредственно перед аварией. Обязательно используйте механизм отложенной регистрации - тот, который выполняет обработку строки позже или в другом потоке, чтобы он сам не влиял на время слишком сильно.

1 голос
/ 15 июля 2010

Знаете ли вы, что вы все еще можете отлаживать сборки релизов?Просто нажмите F5 (а не CTRL + F5), чтобы запустить в режиме отладки.

Это повторяется, то есть вы делаете что-то конкретное, когда происходит срыв?перед сбоем и нажмите F5 для запуска в режиме отладки (убедитесь, что вы используете свою сборку релиза).Затем переходите до тех пор, пока ваше приложение не выйдет из строя.Я обычно нахожу это быстрее, чем добавление логирования и отладки операторов печати. ​​

Если нет, то просто запуск в режиме отладки иногда перехватывает ошибку и останавливается на ошибочной строке.Ответы Амара хорошие: -)

0 голосов
/ 15 июля 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...