Я работаю над многопоточным С++-приложением, которое разлагает кучу. Обычные инструменты для обнаружения этой коррупции кажутся неприменимыми. Старые сборки (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, отмените выбор, пока не найдете проекты, у которых нет правильных настроек (все они имеют правильные настройки).