Отслеживание повреждения памяти на рабочем Linux-сервере

StackOverflow https://stackoverflow.com/questions/1182837

Вопрос

Ребята, не могли бы вы порекомендовать инструмент для обнаружения повреждения памяти на рабочем многопоточном сервере, построенном на C++ и работающем под Linux x86_64?В настоящее время я столкнулся со следующей проблемой:каждые несколько часов мой сервер выходит из строя из-за сбоя сегментации, и дамп ядра показывает, что ошибка возникает в malloc/calloc, что определенно является признаком того, что память где-то повреждена.

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

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

  • Говорят, что ElectricFence сильно пожирает память, но я даже не смог заставить его работать должным образом.Он почти сразу же дает сбой на сценическом сервере в случайных странных местах, где Valgrind вообще не показывал никаких проблем.Может быть, ElectricFence плохо поддерживает многопоточность?..Не имею представления.

  • ДУМА — та же история, что и ElectricFence, но еще хуже.В то время как EF создает дампы ядра с читаемыми обратными трассировками, DUMA показывает мне только «?????» (и да, сервер наверняка построен с флагом -g)

  • dmalloc — я настроил сервер на использование его вместо стандартных процедур malloc, однако через несколько минут он зависает.Присоединение GDB к процессу показывает, что он завис где-то в dmalloc :(

Я постепенно схожу с ума и просто не знаю, что делать дальше.У меня есть следующие инструменты, которые нужно попробовать:mtrace, mpatrol, но, может быть, у кого-то есть идея получше?

Буду очень признателен за любую помощь по этому вопросу.

Обновлять: Мне удалось найти источник ошибки.Однако я обнаружил это на рабочем сервере, а не на производственном, используя helgrind/DRD/tsan - между несколькими потоками произошла гонка данных, что привело к повреждению памяти.Ключевым моментом было правильное подавление valgrind, поскольку эти инструменты показывали слишком много ложных срабатываний.Тем не менее, я не совсем понимаю, как это можно обнаружить на рабочем сервере без каких-либо существенных замедлений...

Это было полезно?

Решение 3

Ребята, мне удалось найти источник ошибки.Однако я нашел это на рабочем сервере с помощью helgrind/DRD/tsan — между несколькими потоками произошла гонка данных, что привело к повреждению памяти.Ключевым моментом было использование правильный подавления valgrind, поскольку эти инструменты показали слишком много ложных срабатываний.Тем не менее, я не совсем понимаю, как это можно обнаружить на рабочем сервере без каких-либо существенных замедлений...

Другие советы

Да, проблемы повреждения памяти C/C++ сложны.Я также несколько раз использовал valgrind, иногда это выявляло проблему, а иногда нет.

При проверке вывода valgrind не старайтесь слишком быстро игнорировать его результат.Иногда, по прошествии значительного времени, вы увидите, что valgrind сначала дал вам подсказку о месте, но вы ее проигнорировали.

Еще один совет — сравнить изменения кода с ранее известной стабильной версией.Это не проблема, если вы используете какую-то систему управления версиями исходного кода (например,свн).Проверьте все функции, связанные с памятью (например.memcpy, memset, sprintf, новый, удаление/удаление[]).

Скомпилируйте вашу программу с gcc 4.1 и ключом -fstack-protector-all.Если повреждение памяти вызвано разрушением стека, это должно быть обнаружено.Возможно, вам придется поиграть с некоторыми дополнительными параметрами SSP.

Попытался ли ты -fmudflap?(прокрутите несколько строк вверх, чтобы увидеть доступные варианты).

вы можете попробовать IBM Purify, но боюсь, что это не открытый исходный код.

Google Perftools с открытым исходным кодом может оказаться полезным, см. проверка кучи документация.

Попробуй это:http://www.hexco.de/rmdebug/Я использовал его широко, он мало влияет на производительность (в основном влияет на объем оперативной памяти), но алгоритм распределения тот же.Этого всегда достаточно, чтобы найти любые ошибки распределения.Ваша программа выйдет из строя, как только произойдет ошибка, и у нее будет подробный журнал.

Я не уверен, что он уловил бы вашу конкретную ошибку, но MALLOC_CHECK_ переменная среды (malloc справочная страница) включает дополнительную проверку в Linux по умолчанию malloc реализации и обычно не требует значительных затрат во время выполнения.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top