Отслеживание повреждения памяти на рабочем сервере Linux - PullRequest
15 голосов
/ 25 июля 2009

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

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

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

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

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

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

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

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

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

Ответы [ 8 ]

7 голосов
/ 26 июля 2009

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

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

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

6 голосов
/ 26 июля 2009

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

4 голосов
/ 01 августа 2009

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

3 голосов
/ 26 июля 2009

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

1 голос
/ 02 августа 2009

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

1 голос
/ 30 июля 2009

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

1 голос
/ 26 июля 2009

Может помочь Google Perftools, который является открытым исходным кодом, см. Документацию heap checker .

1 голос
/ 25 июля 2009

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

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