Как устранить неполадки сбоев в malloc - PullRequest
1 голос
/ 20 сентября 2011

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

Спасибо

Ответы [ 3 ]

9 голосов
/ 20 сентября 2011

Не нарушено ли выделение памяти?

Попробуйте valgrind .

Маллок все еще падает.

Хорошо, я должен предположить, что вы имеете в виду, что SIGSEGV (ошибка сегментации) запускает malloc. Обычно это вызвано повреждением кучи . Повреждение кучи, которое само по себе не вызывает ошибки сегментации, обычно является результатом доступа к массиву за пределами границ массива. Обычно это далеко от точки, где вы звоните malloc.

malloc хранит небольшой заголовок информации "перед" блоком памяти, который он возвращает вам. Эта информация обычно содержит размер блока и указатель на следующий блок. Излишне говорить, что изменение любого из них вызовет проблемы. Обычно указатель следующего блока изменяется на недопустимый адрес, и при следующем вызове malloc он в конечном итоге разыменовывает неверный указатель и ошибки сегментации. Или это не так и начинает интерпретировать случайную память как часть кучи. В конце концов его удача кончилась.

Обратите внимание, что free может случиться так же, если освобождается блок или испорчен список свободных блоков.

Способ обнаружения ошибки такого рода полностью зависит от того, как вы обращаетесь к памяти, которую возвращает malloc. malloc одного struct обычно не является проблемой; это malloc массивов, которые обычно получают вас. Использование отрицательного (-1 или -2) индекса обычно дает вам заголовок блока для вашего текущего блока, а индексирование после конца массива может дать вам заголовок следующего блока. Оба являются допустимыми ячейками памяти, поэтому ошибки сегментации не будет.

Итак, первое, что нужно попробовать, это проверка диапазона. Вы упоминаете, что это появилось на сайте клиента; может быть, это потому, что набор данных, с которыми они работают, намного больше, или что входные данные повреждены (например, он говорит, что выделяет 100 элементов, а затем инициализирует 101), или они выполняют действия в другом порядке (что скрывает ошибку в ваше внутреннее тестирование) или выполнение чего-то, что вы еще не тестировали. Трудно сказать без дополнительных подробностей. Вы должны написать что-нибудь, чтобы проверить правильность ваших входных данных.

0 голосов
/ 11 марта 2019

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

Предполагая, что вы работаете над каким-то * nux, я могу предложить еще один инструмент: electricfence. Цитата:

Electric Fence помогает обнаружить две распространенные ошибки программирования:

software that overruns the boundaries of a malloc() memory allocation,
software that touches a memory allocation that has been released by free().
Unlike other malloc() debuggers, Electric Fence will detect read accesses
as well as writes, and it will pinpoint the exact instruction that causes
an error.

Использование удивительно просто. Просто свяжите свой код с дополнительной библиотекой lefence Когда вы запускаете приложение, основной файл будет сгенерирован при повреждении памяти , а не при использовании поврежденной памяти.

0 голосов
/ 28 февраля 2017

Попробуйте Asan

AddressSanitizer (он же ASan) - это детектор ошибок памяти для C / C ++.Он находит:

Use after free (dangling pointer dereference)
Heap buffer overflow
Stack buffer overflow
Global buffer overflow
Use after return
Use after scope
Initialization order bugs
Memory leaks

Пожалуйста, найдите ссылки, чтобы узнать больше и как его использовать

https://github.com/google/sanitizers/wiki/AddressSanitizer и https://github.com/google/sanitizers/wiki/AddressSanitizerFlags

...