Вопрос

Я пишу библиотеку программирования на основе событий для использования на 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?)
Это было полезно?

Решение

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

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

Другие советы

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

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

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

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

И: Почему этот простой пример потоковой обработки С++ 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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top