Как отладить повреждение памяти в Linux
Я столкнулся с очень умным повреждением памяти в моем C-приложении.
Коррупция происходит при высокой нагрузке.
Поэтому я попытался очистить, valgring, mprotected, а также я попытался написать свой собственный простой механизм защиты.
Purify / Valgring - не помогает, потому что это снижает производительность моего приложения, и проблема не была воспроизведена.
Использование Masttected Jast переместить повреждение в другую область памяти. (потому что это требуется для выравнивания памяти по размеру страницы).
Мой простой механизм защиты не работает, потому что он также снижает производительность.
Как я могу отлаживать свое приложение без снижения производительности?
4 ответа
Purify / Valgring - не помогает, потому что это снижает производительность моего приложения, и проблема не была воспроизведена.
Читая это, я полагаю, что у вас есть не только повреждение памяти, но и одно или несколько состояний гонки.
Так что я бы дал вам задание сначала побежать с helgrind, чтобы найти условия гонки. Но helgrind не знает о порядке памяти, если вы используете std::atomic
, В этом случае он сообщает о ложных срабатываниях и является более или менее непригодным для использования. Для этой ситуации я не знаю ни одного инструмента, который проверяет упорядочение памяти, что является большой проблемой в данный момент.
Как я могу отлаживать свое приложение без снижения производительности?
Вопрос: почему ваша неудача зависит от производительности? Есть ли у вас параллельный ввод или запуск нескольких задач / потоков? Если это так, уменьшите скорость выполнения этих задач, потоков или ввода-вывода, возможно, вы можете принудительно вызвать ошибку.
Подсказки для замедления других потоков / задач: В linux вы можете привязать поток / задачу к процессору / ядру и, надеюсь, вы можете потреблять больше энергии на этом одном ядре, добавляя несколько задач "стопора" также на этом ядре. набор задач. Вы также можете компилировать специальные части вашего кода с -O0
или другие хаки.
Я знаю, это настоящий кошмар, чтобы найти ошибки, которые ушли, если у вас есть инструменты отладки на месте. Но мы ничем не можем помочь, так как нам не на что взглянуть... так что немного читаем хрустальный шар!
использовать дезинфицирующее средство:
добавлять-fsanitize=address
или-fsanitize=thread
на ваших флагах компиляции, и это, вероятно, укажет вам на дефекты.
Вы также можете добавить-O0
для удаления оптимизации (лучшие обратные трассировки) и-g
чтобы сохранить символы/информацию об отладке в вашем двоичном файле.
Если у вас есть 64 бит, вы можете использовать пользовательский malloc()
это всегда делает mmap()
и обычай free()
это делает munmap()
и другой mmap()
на той же памяти. Защитите этот материал мьютексом, чтобы избежать смертельной гонки. Это изменяет поведение на ошибку при первом доступе к освобожденной памяти.
Если он не находит, настройте пользовательский malloc()
переместить выделенный буфер как можно выше в области отображения.
Обратите внимание, что вы не можете сделать это в 32 битах, потому что это сжигает адресное пространство как сумасшедший.