Чистый виртуальный метод называется — кросс-компиляция

Я пишу библиотеку событий на основе событий для использования на BeagleBone Black и обнаружил странную ошибку.

Когда я компилирую точно такой же код с точно такими же флагами, я получаю следующие ошибки на процессоре на основе ARM, но не при запуске кода, скомпилированного для моего компьютера x86.

$ ./missionControl
pure virtual method called
pure virtual method called
pure virtual method called
terminate called recursively
terminate called recursively
Aborted

Когда я собираю и запускаю на своем ноутбуке, программа работает правильно.

Это команда, которую я использую для компиляции (я использую Makefile, но оба метода компиляции демонстрируют абсолютно одинаковое поведение):

g++ -std=gnu++11 -pthread -O3 -D_GLIBCXX_USE_NANOSLEEP -o missionControl `find . -name *.cpp`

Неважно, буду ли я кросс-компилировать с Ubuntu arm-linux-gnueabi-g++ или ARM-совместимый g++ на фактической BeagleBone я все еще получаю ошибки на ARM.

У меня такой вопрос: что может быть причиной этой ошибки, и что я могу сделать, чтобы попытаться найти источник? Почему это произошло на одной процессорной архитектуре, а не на другой, для той же версии G ++?

Спасибо!

Вот след от GDB процессора ARM:

#0  0xb6d4adf8 in raise () from /lib/libc.so.6
#1  0xb6d4e870 in abort () from /lib/libc.so.6
#2  0xb6f50ab4 in __gnu_cxx::__verbose_terminate_handler() () from /usr/lib/libstdc++.so.6
#3  0xb6f4ea4c in ?? () from /usr/lib/libstdc++.so.6
#4  0xb6f4ea4c in ?? () from /usr/lib/libstdc++.so.6
Backtrace stopped: previous frame identical to this frame (corrupt stack?)

4

Решение

Проблема оказалась из-за ошибки в ARM-версии libstdc ++, которая работает на BeagleBone. Маленькая игрушечная программа, у которой вообще нет виртуальных функций, вызывает ту же ошибку («вызывается чисто виртуальная функция») при создании std :: thread.

Я собираюсь попытаться скомпилировать собственную версию gcc / libstdc ++ 4.8 на самой BeagleBone — даже если это займет много времени.

4

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

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

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

Просто подключите к программе отладчик и посмотрите, какая виртуальная функция вызывается и откуда.

2

Увидеть: https://groups.google.com/forum/#!topic/automatak-dnp3/Jisp_zGhd5I

А также: Почему этот простой пример многопоточности c ++ 11 не работает при компиляции с помощью clang 3.2?

Теперь я понятия не имею, почему это работает, но, по крайней мере, для меня. Добавьте следующие четыре определения препроцессора в командную строку компилятора:

__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1
__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2
__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8

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

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