Как отладить ошибки повреждения кучи? - PullRequest
160 голосов
/ 18 июня 2009

Я отлаживаю (нативное) многопоточное приложение C ++ в Visual Studio 2008. В случайных, на первый взгляд, случаях я получаю сообщение об ошибке «Windows запустила точку останова ...» с замечанием, что это может быть связано с коррупция в куче. Эти ошибки не всегда сразу вызывают сбой приложения, хотя, скорее всего, вскоре после этого произойдет сбой.

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

  • Какие вещи могут вызвать эти ошибки?

  • Как мне их отладить?

Советы, инструменты, методы, просветления ... приветствуются.

Ответы [ 14 ]

1 голос
/ 18 июня 2009

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

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

0 голосов
/ 31 октября 2016

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

Итак, в дополнение к другим ответам:

Что может вызвать эти ошибки? Что-то повреждено в файле сборки.

Как мне их отладить? Очистка проекта и перестройка. Если это исправлено, скорее всего, это проблема.

0 голосов
/ 23 мая 2012

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

  • Удаление элементов из коллекции STL во время итерации (я думаю, что в Visual Studio есть флаги отладки, чтобы отлавливать эти вещи; я обнаружил это во время проверки кода)
  • Этот более сложный, я разделю его на шаги:
    • Из нативного потока C ++ перезвоните в управляемый код
    • На управляемой земле позвоните Control.Invoke и избавьтесь от управляемого объекта, который обертывает собственный объект, к которому относится обратный вызов.
    • Поскольку объект все еще жив в собственном потоке (он останется заблокированным при обратном вызове, пока Control.Invoke не закончится). Я должен уточнить, что я использую boost::thread, поэтому я использую функцию-член в качестве функции потока.
    • Решение : Вместо этого используйте Control.BeginInvoke (мой графический интерфейс сделан с Winforms), чтобы собственный поток мог завершиться до того, как объект будет уничтожен (целью обратного вызова является точное уведомление о том, что поток завершился и объект можно уничтожить).
0 голосов
/ 07 ноября 2011

Вы можете использовать макросы VC CRT-Heap-Check для _CrtSetDbgFlag : _CRTDBG_CHECK_ALWAYS_DF или _CRTDBG_CHECK_EVERY_16_DF * 100 * 100 * * * * * * * * * * * * * * * *.

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