Я работаю над многопоточным С++-приложением, которое разлагает кучу. Обычные инструменты для обнаружения этой коррупции кажутся неприменимыми. Старые сборки (18 месяцев) исходного кода демонстрируют то же поведение, что и самый последний выпуск, так что это было давно и просто не было замечено; с другой стороны, исходные дельта не могут использоваться для определения того, когда была введена ошибка - в репозитории много изменений кода.
Запрос на сбои в поведении - это генерация пропускной способности в этой системе - передача сокетов данных, которая переводится во внутреннее представление. У меня есть набор тестовых данных, которые будут периодически вызывать исключение приложения (различные места, различные причины, в том числе отказ от кучи, а именно: повреждение кучи).
Поведение, по-видимому, связано с мощностью процессора или пропускной способностью памяти; чем больше у каждой машины, тем легче она будет разбиваться. Отключение гиперпотокового ядра или двухъядерного ядра снижает скорость (но не устраняет) коррупцию. Это указывает на проблему, связанную с синхронизацией.
Теперь вот руб:
Когда он запускается под легкой средой отладки (скажем, Visual Studio 98 / AKA MSVC6
), размножение кучи можно легко воспроизвести - пропущено десять или пятнадцать минут, прежде чем что-то терпит неудачу, и исключения, например, alloc;
при работе в сложной среде отладки (Rational Purify, VS2008/MSVC9
или даже Microsoft Application Verifier), система становится привязанной к скорости памяти и не падает (привязана к памяти: процессор не становится выше 50%
, свет на диске не включен, программа идет так быстро, поле, потребляющее 1.3G
2G ОЗУ). Итак, У меня есть выбор между возможностью воспроизвести проблему (но не идентифицировать причину) или быть способным идентифицировать причину или проблему, которую я не могу воспроизвести.
Мои текущие лучшие предположения о том, где к следующему:
- Получите безумно хруповую коробку (чтобы заменить текущий dev dev: 2Gb RAM в
E6550 Core2 Duo
); это позволит воспроизвести крах, вызывающий неправильное поведение при работе в мощной среде отладки; или - Перепишите операторы
new
иdelete
, чтобы использоватьVirtualAlloc
иVirtualProtect
, чтобы пометить память как доступную только для чтения, как только это будет сделано. Выполнить вMSVC6
и заставить ОС поймать плохого парня, который пишет освобожденную память. Да, это признак отчаяния: кто ад переписываетnew
иdelete
?! Интересно, будет ли это делать так же медленно, как в Purify et al.
И, нет: доставка с помощью инструмента "Очистка" не является вариантом.
Коллега просто прошел мимо и спросил: "Переполнение стека? Теперь мы получаем переполнение стека?!?"
И теперь вопрос: Как найти кукурузный корруптор?
Обновление: балансировка new[]
и delete[]
, похоже, имеет большой путь к решению проблемы. Вместо 15 минут приложение теперь идет примерно за два часа до сбоя. Еще нет. Какие-нибудь дополнительные предложения? Повреждение кучи сохраняется.
Обновление: сборка выпуска в Visual Studio 2008 выглядит значительно лучше; текущее подозрение основывается на реализации STL
, которая поставляется с VS98
.
- Воспроизводите проблему.
Dr Watson
создаст дамп, который может быть полезен при дальнейшем анализе.
Я запомню это, но я обеспокоен тем, что д-р Уотсон будет только споткнуться после факта, а не когда куча начнет топать.
Другая попытка может быть использована
WinDebug
как инструмент отладки, который достаточно мощный и одновременно легкий.
Получил, что происходит в данный момент, опять же: не очень помогает, пока что-то не пойдет не так. Я хочу поймать вандала в акте.
Возможно, эти инструменты позволят вам, по крайней мере, ограничить проблему определенным компонентом.
Я не очень надеюсь, но отчаянные времена требуют...
И вы уверены, что все компоненты проекта имеют правильные настройки библиотеки времени выполнения (
C/C++ tab
, категория генерации кода в настройках проекта VS 6.0)?
Нет, я не, и завтра я проведу пару часов, пройдя через рабочую область (58 проектов) и проверим, что все они компилируются и связаны с соответствующими флагами.
Обновление: это заняло 30 секунд. Выберите все проекты в диалоговом окне
Settings
, отмените выбор, пока не найдете проекты, у которых нет правильных настроек (все они имеют правильные настройки).