سؤال

لدي حاليًا مشكلة في تنفيذ السيناريو التالي باستخدام التكوين التالي: GCC 3.4 ، Linux.

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

في البداية كانت فكرتي هي وضع المدخلات في الذاكرة المليئة (Linux Mmap-Syscall) وحماية (mprotect) الصفحة الأخيرة ، ضد الوصول. من خلال تثبيت معالج SIGSEGV الخاص ، يمكن للتطبيق أن يرمي استثناء (عند تجميعه باستخدام استثناءات GCC -FNON-CALL). سيؤدي هذا الاستثناء إلى مقاطعة قراءة C lib. لقد عرفت أن هذا lib لا يخصص أي ذاكرة (أو موارد أخرى) ، والتي قد تضيع أثناء الترتيب المكدس. كان السيناريو بالكامل يعمل بشكل جيد في اختبارات وحدتي ، حيث كان كل شيء تطبيق C ++ واحد. ولكن الآن عندما يسمى رمز C من LIB يسمى تطبيقي فقط ... هل أحتاج إلى إعادة بناء هذا C-SO مع علامة استثمار -FNON-CALL-Calls أيضًا؟ لا يمكنني تجميع هذا lib ، ولكن إعادة ربطه فقط ، لأن لديّ الوصول إلى ملفات OBJ فقط.

هذه هي صورة بيئة التنفيذ:

+------------C++ APP----------+
|                             |
| Install SIGSEGV handler     |
| code calling C SO functions |
|                             |
|   +----------C SO Functions------------+
|   |   execute producing SIGSEGV        |
|   +------------------------------------+
|                             |
| SIGSEGV Handler called      |
|   => throw Exception        |
|      to stop execution of   |
|      C function             |
+-----------------------------+

اقتراحات أخرى موضع ترحيب.

شكرا جزيلا،

Ovanes


ملاحظة: أرى بعض الاقتراحات والنقاد لكنهم ليسوا جميعهم بمثابة عيب. إليكم السبب: لدي واجهة واحدة فقط ، حيث يمكنني الارتباط بالمكتبة. يتم استخدام المكتبة لفك تشفير هياكل البيانات. المشكلة هي أنه إذا كان لدي صفيف بطول -1 ، تبدأ المكتبة في فك تشفير مجموعة الطول 0xffffff (على نظام 32 بت). الانتظار حتى تعطل LIB في عملية منفصلة ليس خيارًا في رأيي. بادئ ذي بدء ، ستستغرق فك التشفير من الوقت الذي يمكن الاعتماد عليه من جهة وسوف ينتج الكثير من القمامة من جهة أخرى. نظرًا لأن أداتي تحتاج إلى إظهار الإخراج الذي تم فك تشفيره بشكل موثوق للمستخدمين. وما زالوا بحاجة إلى أن يكونوا قادرين على فهم الآثار.

لا أرى النقطة هنا للعمل حول sigsegv. بادئ ذي بدء ، تقرأ المكتبة البيانات وتكتبها إلى مقبض الملف الذي مررت به من قبل. يمكنني تكوين كيفية الكتابة إلى هذا المقبض (مخزنة أم لا). علاوة على ذلك ، أعرف بالضبط أنه لا يخصص أي بيانات أو موارد كومة. وأخيراً ، يحاول الوصول إلى الذاكرة التي يحميها تطبيقي لتجنب مثل هذه الأخطاء. من وجهة نظر المستخدم ، لا يمكنني إخبار شخص ما: آسف لأن التتبع الثنائي كان نصف قابلاً للتخلص منه فقط ، لأن بعض البيانات كانت غير متسقة. أعلم أن هذه البيانات كانت غير مقلقة وأعرف بالضبط كيفية التعامل مع هذا التناقض. لذلك يمكنني التعافي بأمان. أعتقد أنني سأحاول استخدام وظائف SIGSetJMP/SiglongJMP POSIX وآمل أن يكونوا أفضل استثناءً. في الواقع ، إما setjmp/longjmp أو sigsetjmp/siglongjmp تستخدم لتنفيذ الاستثناءات.

نعم ، قمت بتصحيح طلبي وأرى أن مكدس الاتصال صالح.

هل كانت مفيدة؟

المحلول 3

حسنا يا رفاق،

لقد فعلت ذلك مع sigsetjmp/siglongjmp. يعمل كالسحر. يمكنني القفز فوق الوظيفة في كومة وظيفة المتصل والقيام بمعالجة الأخطاء هناك.

شكرا لجميع الاقتراحات.

تحياتي الحارة،

Ovanes

نصائح أخرى

لسوء الحظ ، ليس لدي إجابة للمشكلة كما هو مذكور - هل حاولت تشغيل طلبك تحت تصحيح الأخطاء ، لمعرفة أين ينتهي بالضبط؟

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

قد يكون هذا سؤالًا غبيًا ، ولكن يجب فحص الملف الأساسي؟ أو قم بتشغيل طلبك في Debugger؟

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