سؤال

أنا أكتب مكتبة برمجة قائمة على الأحداث لاستخدامها على 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?)
هل كانت مفيدة؟

المحلول

تبين أن المشكلة ناتجة عن خطأ في إصدار ARM من libstdc++ الذي يعمل على BeagleBone.يتسبب برنامج لعبة صغير لا يحتوي على وظائف افتراضية على الإطلاق في حدوث نفس الخطأ ("تسمى وظيفة افتراضية خالصة") عند إنشاء std::thread.

سأحاول تجميع إصدار مخصص من gcc/libstdc++ 4.8 على BeagleBone نفسه - حتى لو استغرق الأمر وقتًا طويلاً.

نصائح أخرى

ال طريقة افتراضية نقية تسمى يحدث الخطأ عند محاولة استخدام الإرسال الديناميكي لاستدعاء وظيفة افتراضية خالصة في قاعدة قبل إنشاء النوع المشتق الذي ينفذها أو بعد تدميرها بالفعل.

السبب الأكثر شيوعًا لذلك هو إذا حاولت الفئة الأساسية استدعاء دالة افتراضية خالصة عند هذا المستوى من خلال المنشئ أو المدمر.بخلاف ذلك، كما تمت الإشارة إليه في بعض التعليقات، إذا حاولت الوصول إلى كائن ميت، فقد تواجه أيضًا نفس المشكلة.

ما عليك سوى إرفاق مصحح الأخطاء بالبرنامج ومعرفة الوظيفة الافتراضية التي يتم استدعاؤها ومن أين.

يرى: 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

لم أجرب لمعرفة ما إذا كانت جميعها مطلوبة، أو ما إذا كان يمكنك الإفلات ببعضها فقط أم لا.ولكن هذا حل المشكلة بالنسبة لي.شكرًا لمن كتب الإجابات أعلاه، وشكرًا لزملائي الذين تفوقوا علي في جوجل :)

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top