Один и тот же программный код с одним и тем же компилятором приводит к разным двоичным файлам

У меня есть проблема с моим кодом, которая имеет некоторые очень странные симптомы.

  1. Код скомпилирован на моем компьютере со следующими версиями:

    а. Версия GCC: 4.4.2

    б. CMAKE verson: 2.8.7

    с. QNX (операционная система) версия: 6.5.0

И в коде есть ошибка, в то время как освобождается некоторая память и происходит выход из функции (не умирая ни при каком коде, просто при выходе из функции).

Странные вещи об этом:

  1. Код делает это в режиме выпуска, но не в режиме отладки:

    а. Код является многопоточным, так что это указывает на состояние гонки.

    б. Я не могу отладить, переведя его в режим отладки.

  2. Код, скомпилированный на компьютере коллеги с одинаковыми версиями всего, не имеет этой проблемы.

    а. Самое странное в этом то, что код рабочих партнеров работает, но также и то, что двоичный файл, созданный в результате компиляции на его машине, то есть примерно на 6 МБ больше.

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

Поскольку я использую QNX, я ограничен в своих средствах отладки, я не могу использовать Valgrind, и, поскольку он не поддерживается в QNX, GDB на самом деле не помогает.

Я ищу любого, у кого была подобная / та же самая проблема и какова была причина и как они исправили это.

РЕДАКТИРОВАТЬ:

Оооо … Я узнал, что это было, но я все еще немного озадачен тем, как это произошло.

Код виновника был такой:

Eigen::VectorXd msBb = data.modelSearcher->getMinimumBoundingBox();

где определение для getMinimumBoundingBox это:

Eigen::VectorXd ModelSearcher::getMinimumBoundingBox();

и он возвращает VectorXd, который всегда инициализируется как VectorXd output(6, 1), Так что я сразу подумал, правильно, это должно быть потому, что VectorXd не инициализируется, а изменяет его следующим образом:

Eigen::VectorXd msBb(6, 1); msBb = data.modelSearcher->getMinimumBoundingBox();

Но это не сработало. На самом деле мне пришлось исправить это, изменив определение функции следующим образом:

void ModelSearcher::getMinimumBoundingBox(Eigen::MatrixXd& input);

и призыв к этому

Eigen::VectorXd msBb(6, 1); data.modelSearcher->getMinimumBoundingBox(msBb);

Итак, теперь новый вопрос:

Что за черт? Почему первая смена не сработала, а вторая сработала, почему я должен пройти по ссылке? О, и большой вопрос, как, черт возьми, это не сломалось, когда мой коллега скомпилировал его, и я запустил его? Это прямая ошибка памяти, конечно, это не должно зависеть от того, какой компьютер его компилирует, тем более что компилятор и все другие важные вещи одинаковы !! ??

Спасибо за помощь ребята.

8

Решение

… двоичный файл, созданный в результате компиляции на его компьютере, который составляет примерно 6 МБ больше

Стоит выяснить, в чем разница (даже если это только тот случай, когда его сборка скрывает, а ваша разоблачает настоящую ошибку):

  • перепроверьте, что вы компилируете точно такой же код (нет незафиксированных локальных изменений, нет дополнительных заголовков в пути поиска include и т. д.)
    • тройная проверка путем добавления -E переключитесь на ваши аргументы gcc в cmake, чтобы он предварительно обрабатывал ваши файлы с тем же путем включения, что и при обычной компиляции; diff выход препроцессора
  • сравнить вывод из nm или же objdump или что вам нужно для двух связанных исполняемых файлов: если какая-то системная или сторонняя библиотека представляет собой другую версию на одном компьютере, она может отображаться здесь
  • сравнить вывод из ldd если он динамически связан, убедитесь, что они оба получают одинаковые версии библиотеки
    • сравнить версии библиотеки это на самом деле получает во время выполнения тоже, если это возможно. Надеюсь, вы можете сделать одно из: беги pldd, сравните .so записи в /proc/pid/map, запустите процесс под strace/dtrace/truss и сравните активность компоновщика во время выполнения

Что касается кода … если это не работает:

Eigen::VectorXd ModelSearcher::getMinimumBoundingBox();
// ...
Eigen::VectorXd msBb(6, 1); msBb = data.modelSearcher->getMinimumBoundingBox();

и это делает:

void ModelSearcher::getMinimumBoundingBox(Eigen::MatrixXd& input);
// ...
Eigen::VectorXd msBb(6, 1); data.modelSearcher->getMinimumBoundingBox(msBb);

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

Обратите внимание, что если оператор вообще не определен, по умолчанию это мелкая копия.

7

Другие решения

Вы сказали, что должны измениться с:

void ModelSearcher::getMinimumBoundingBox(Eigen::MatrixXd& input);

Что это было раньше?

Если бы это было:

void ModelSearcher::getMinimumBoundingBox(Eigen::MatrixXd input);

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

Пожалуйста, проверьте, как они оба реализованы. Вот немного информации это может помочь.

0

По вопросам рекламы [email protected]