valgrind - разные результаты с hellgrind против утечки - PullRequest
0 голосов
/ 05 ноября 2018

У меня странное поведение, которого я не понимаю. Код немного сложен, поэтому я воздержусь от публикации здесь и вместо этого опишу поведение и надеюсь, что у кого-то, зная, как работает valgrind, есть идея, что я могу продолжить , несмотря на эту небольшую информацию.

Справочная информация:

Я разрабатываю некоторые дополнительные функции для платформы моделирования на основе агентов с открытым исходным кодом на основе c / c ++ fork @ my github . Компиляция в порядке. Кажется, все работает, как и должно быть, на основании моей проверки с помощью тестовых программ. Кроме того, valgrind не сообщает об ошибках, имеющих отношение к делу. Но воспроизводимость (что крайне важно) странная.

Внутри фреймворка определяется файл модели (в основном, инициализация прогона симуляции). Основываясь на этом файле, нужно иметь возможность воспроизводить точно такой же вывод (и не зависит от платформы). Это работает следующим образом: если я запускаю среду моделирования (версия с графическим интерфейсом), загружаю файл и запускаю его, он каждый раз выдает один и тот же результат. Кроме того, используя версию командной строки, я получаю одни и те же результаты каждый раз.

Но, если из запущенного экземпляра среды моделирования я запускаю одну и ту же модель более одного раза, возникает странное поведение - иногда ...

Используемые опции компилятора:

CC=g++
GLOBAL_CC=-march=native -std=gnu++14
SSWITCH_CC=-fnon-call-exceptions -Og -ggdb3 -Wall

Настройка:

Я запускаю скомпилированный файл и трижды выполняю фиксированную настройку симуляции внутри программы. Теперь он должен давать одинаковые результаты каждый раз, что я проверяю, печатая случайные числа на разных этапах.

Странное поведение:

Вариант № 1:

Когда я запускаю программу в valgrind, используя параметры:

valgrind --leak-check=full --leak-resolution=high --show-reachable=yes

Внутренне я не получаю таких же результатов

Отчет из варианта 1:

Finished processing sim1
==6206==
==6206== HEAP SUMMARY:
==6206==     in use at exit: 43 bytes in 1 blocks
==6206==   total heap usage: 4,124,309 allocs, 4,124,308 frees, 888,390,511 bytes allocated
==6206==
==6206== 43 bytes in 1 blocks are still reachable in loss record 1 of 1
==6206==    at 0x4C2DDCF: realloc (vg_replace_malloc.c:785)
==6206==    by 0x5BE7FB2: getcwd (getcwd.c:84)
==6206==    by 0x143391: lsdmain(int, char**) (lsdmain.cpp:203)
==6206==    by 0x10C37D: main (main_gnuwin.cpp:29)
==6206==
==6206== LEAK SUMMARY:
==6206==    definitely lost: 0 bytes in 0 blocks
==6206==    indirectly lost: 0 bytes in 0 blocks
==6206==      possibly lost: 0 bytes in 0 blocks
==6206==    still reachable: 43 bytes in 1 blocks
==6206==         suppressed: 0 bytes in 0 blocks
==6206==
==6206== For counts of detected and suppressed errors, rerun with: -v
==6206== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

Вариант № 2

Однако, когда я использую следующую опцию вместо:

valgrind --tool=helgrind

Я получаю одинаковые результаты каждый раз с версией командной строки. Интересно, что первые результаты с опцией # 1 совпадают с результатами с опцией № 2.

Буду рад любым предложениям. И я не обученный специалист по информатике ... Я использую и mt1937 (каждый раз переинициализируется) - но начальные случайные числа между симуляциями одинаковы, поэтому я не думаю, что ошибка заключается здесь. Хотя позже в ходе выполнения случайные числа изменяются в варианте № 1 (это мой тест, помимо времени, необходимого для моделирования, чтобы найти равновесие).

1 Ответ

0 голосов
/ 30 ноября 2018

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

std::sort( vector.begin(),vector.end() ); // vector of std::pairs<double, pointer>

Решение, очевидно, состоит в том, чтобы сортировать только по первому элементу пары:

std::sort( vector.begin(),vector.end(), [](auto const &A, auto const &B ){return A.first < B.first; } );

Несколько замечаний о том, почему я не нашел эту проблему напрямую:

  • Когда я реализовал этот вид, я намеревался сделать его "стабильным". Указатели объектов являются своего рода уникальными, поэтому в разных подмножествах порядок будет одинаковым, а также независимо от того, как я добавляю элементы в набор.
  • Я не учел, что значения указателя являются (не точно, но в действительности) случайными числами вне моего контроля.
  • Я этого не видел, потому что каким-то образом ОС (или что-то еще) всегда присваивает одинаковые значения указателя между различными вызовами программы (я полагаю, что существует «виртуальное» пространство, которое всегда инициализируется снова). Из-за этого я не предполагал, что проблема в указателях.
  • Любопытно, что когда я запустил программу с Valgrind и опцией --tool=helgrind, проблема не исчезла. Одно из предложений, которое я получил (в автономном режиме), заключалось в том, что memcheck предварительно инициализирует память по заданному шаблону, и это было бы ответом, если бы причиной были неинициализированные переменные. Похоже, что helgrind также управляет памятью в разных областях, предоставляя для каждого из моих последующих имитаций «свежую» виртуальную память, чтобы сортировка указателей была стабильной в повторяющемся цикле.

Надеюсь, это кому-нибудь поможет, если он столкнется с такими же проблемами. Спасибо за все предложения!

...