Сбой жесткого отслеживания памяти – при работе с Valgrind выполняется правильно, без ошибок

У нас есть сложная программа, которая хорошо работает на входе с большими нагрузками (на самом деле любой вход) без применения многопоточности.
Мы реализовали multithreading с помощью threadpool, и, учитывая эти входные параметры, я получаю следующие результаты:
( Примечание : где я не говорю об ошибках , это означает, что я тестировал valgrind -v и когда я говорю, что нет утечек памяти , это означает, что я проверил его с valgrind --leak-check=full -v ).

  1. small_file: успешно работает с более чем 1 работником (streamами), без ошибок valgrind, без утечек памяти
  2. medium_file: с 1 рабочим выполняется успешно, нет ошибок / утечек памяти. С> 1 работником я получаю: a. обычно ошибка кучи коррупции, b. дважды бесплатно. При работе с valgrind -v с> 1 работником программа завершается успешно. Кроме того, из valgrind не печатаются ошибки, то есть ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2) .

Теперь, когда я не получаю никаких ошибок от valgrind, что я могу сделать, чтобы найти проблему с повреждением памяти в этом сложном и большом приложении?

Среда разработки:
Версия Ubuntu, 64bit, gcc: 4.7.2 и 4.8.1 (разные компьютеры, более новая версия Ubuntu).

С> 1 работником я получаю: a. обычно ошибка кучи коррупции, b.double-free. При работе с valgrind -v с> 1 работником программа успешно завершается

Основываясь на вышеуказанных симптомах, мне кажется, что в вашей программе происходит определенная проблема синхронизации. Похоже, ваша программа делится адресом памяти кучи между streamами и, следовательно, всякий раз, когда есть какая-то гонка данных, перед вами стоит проблема.

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

Сказав это, я думаю, что нет таких способов, чтобы найти такие ошибки в больших программах. Однако я сильно подозреваю, что существует некоторый сценарий гонок данных, который приводит к повреждению памяти / двойному свободному. Таким образом, вы можете захотеть использовать Helgrind для проверки / поиска информации о гонке / streamе данных, которая может привести к повреждению памяти.

Теперь, когда я не получаю никаких ошибок от valgrind, что я могу сделать, чтобы найти проблему с повреждением памяти в этом сложном и большом приложении?

Хорошо, позвольте мне описать вам, что я сделал, чтобы найти утечки памяти в реализации Microsoft в JavaScript еще в 1990-х годах.

Сначала я убедился, что в отладочной версии моей программы, как можно больше распределений памяти, направляются к тем же вспомогательным методам. То есть, я переопределял malloc , new и т. Д., Чтобы все были синонимами для распределителя, который я написал сам.

Этот распределитель был просто тонкой оболочкой вокруг операционного распределителя памяти виртуальной кучи операционной системы, но у нее были некоторые дополнительные умения. Он выделял дополнительную память в начале и конце блока и заполнял ее с помощью значений дозорных, количество streamобезопасности количества распределений до сих пор и streamовый двухсвязный список всех распределений. «Свободная» процедура проверила бы, что дозорные значения с обеих сторон все еще остаются нетронутыми; если нет, то где-то есть повреждение памяти. Это отделит блок от связанного списка и освободит его.

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

Эти инструменты позволили мне очень легко найти утечки памяти и повреждения памяти в реальном времени.

Пожалуйста, используйте CORE DUMP :: [в основном он используется в двойных ошибках, обнаруженных glibc-типах]

Скомпилируйте свою программу с опцией gcc -g для отладочной информации

ulimit -a

он покажет вам размер основного файла

ulimit -c неограниченно

он установит размер основного файла без ограничений

теперь запустите программу, затем в вашем текущем каталоге файл будет генерировать имя «core»,

затем проанализируйте его GDB, как показано ниже.

gdb ./youprogram core

GDB) Б.Т.

он покажет вам, где проблема.

если вы найдете какие-либо трудности, напишите мне …