2016-04-12 9 views
0

Мы столкнулись с крахом в приложении Windows C++ сразу при запуске. В настоящее время авария происходит только на нашей машине с выигрышем 8.1 (другие машины для разработки, являющиеся окнами 7), и происходят только в версиях релизов. Трассировка стека каждый раз немного отличается, но всегда связана с распределением памяти, поэтому это, вероятно, проблема с кучей коррупции.Кучное повреждение, вызванное состоянием гонки - не происходит, когда приложение замедляется. Как отлаживать?

Проблема заключается в том, что, как только приложение немного замедлилось, авария не происходит:

  • Debug сборки не врезаться.

  • Если приложение для сборки выпуска связано с отладочным crt (статическим или динамическим), авария не возникает, поэтому куча отладки CRT не может использоваться для отслеживания проблемы.

  • Если приложение Application подключено к приложению и выбраны тесты «кучи», приложение не будет аварийно завершено.

  • Запуск приложения через «Dr.Memory» также приводит к тому, что авария не происходит.

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

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

ответ

0

Поведение, о котором вы описали, может сигнализировать о том, что у вашего SW есть проблема с динамической памятью, которая чувствительна к времени. Я бы рекомендовал только обзор кода с акцентом на переменные, используя динамическое распределение данных или ссылки на динамически распределенные данные. В частности, контейнеры из stl, любые другие объекты, выделенные через new/malloc или аналогичные. Возможно, в первую очередь вы можете найти все такие переменные, которые разделены между разными потоками, и проанализировать, есть ли:

  1. Переменные инициализируются до первого использования.
  2. Срок службы объектов более точен, чем их использование. Для данных это означает, что он не должен использоваться до его выделения и после его освобождения.
  3. Переменные защищены от одновременного чтения/записи из разных потоков.
  4. Логическая последовательность чтения и записи гарантирует, что чтение переменной безопасно в случае, если переменная еще не написана кем-либо.

Если ничего не найдено, выполните затем некоторый статический анализ кода (т. Е. LINT или аналогичный) и проанализируйте все предупреждения компилятора, если они у вас есть.

Обновлено: еще одна возможность, вы можете переопределить свои собственные распределители памяти, чтобы добавить в выделенную память и некоторые контрольные точки, чтобы предотвратить повреждение паттернов. Как только это произойдет, вы можете, по крайней мере, сбросить данные, а вместе с callstack определить место в SW, которое в первую очередь затронуто коррупцией. Тогда объем анализа будет значительно сокращен. Но не забывайте, что это также может изменить тайминги, чтобы коррупция не произошла.