هل يمكنك فرض حادث تصادم في حالة حدوث كتابة لموقع ذاكرة معين بأدق من تفريغ الصفحة؟

StackOverflow https://stackoverflow.com/questions/2484959

سؤال

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

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

يمكنني محاولة منع العملاء من الكتابة فوقها من خلال إعلان الأعضاء في الرأس الذين يستخدمونهم كـ const ، لكن هذا لن يمنع فساد الذاكرة (فائض المخزن المؤقت ، الممثلات السيئة ، إلخ) من الكتابة فوقها. يمكنني إدخال الكناري, ، ولكن بعد ذلك يجب أن أدفع باستمرار تكلفة التحقق منها.

بدلاً من تخزين عضو عدد المرجعية مباشرة ، يمكنني تخزين مؤشر للبيانات الفعلية في صفحة كتابة تم تعيينها فقط ، مع الحفاظ على الهياكل في الصفحات المعينة فقط. سيعمل هذا ، سيؤدي نظام التشغيل إلى إجبار طلبي على التعطل إذا حاولت الكتابة إلى البيانات الموضحة ، ولكن يمكن أن يكون التخزين غير المباشر غير مرغوب فيه عند محاولة الكتابة قفل الخوارزميات الحرة, ، لأن الحاجة إلى اتباع مستوى آخر من عدم التوجيه يمكن أن يتغير ما إذا كان يمكن القيام بشيء ما.

هل هناك أي طريقة لتمييز المناطق الأصغر من الذاكرة بحيث أن كتابتها ستؤدي إلى تفجير تطبيقك؟ تحتوي بعض المنصات على نقاط مراقبة للأجهزة ، وربما يمكنني تنشيط أحد الأشخاص الذين لديهم تجميع مضمّن ، لكنني سأقتصر على 4 في وقت واحد فقط على 32 بت X86 ويمكن لكل واحد تغطية جزء من البنية فقط لأنهم محدودون إلى 4 بايت. كما أنه سيجعل برنامجي مؤلمًا للتصحيح ؛)

تحرير: لقد وجدت هذه الورقة التي تفرقع العين, ، لكن لسوء الحظ ، يتطلب استخدام ذاكرة ECC ونواة Linux المعدلة.

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

المحلول

لا أعتقد أنه من الممكن جعل بعض البتات تقرأ فقط مثل هذا على مستوى نظام التشغيل.

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

long *refCountersBase;//The start address of the ref counters page
MyStruct *structsBase;//The start address of your structures page

//get address to reference counter
long *getRefCounter(MyStruct *myStruct )
{
    size_t n = myStruct - structsBase;
    long *ref = refCountersBase + n;
    return ref;
}

نصائح أخرى

ستحتاج إلى إضافة معالج الإشارة لـ SIGSEGV الذي يتعافى من الاستثناء ، ولكن فقط لبعض عناوين. قد تكون نقطة البداية http://www.opengroup.org/onlinepubs/009695399/banedefs/signal.h.html والوثائق المقابلة لنظام التشغيل الخاص بك.

تعديل: أعتقد أن ما تريده هو تنفيذ الكتابة والعودة إذا كان عنوان الكتابة على ما يرام بالفعل ، ومكمل ذيل معالج الاستثناء السابق (المؤشر الذي تحصل عليه عند تثبيت معالج الاستثناء الخاص بك) إذا كنت ترغب في نشر الاستثناء. أنا لست من ذوي الخبرة في هذه الأشياء رغم ذلك.

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

يمكنك كتابة واجهة برمجة تطبيقات بدلاً من مجرد استخدام الرؤوس. سيؤدي إجبار العملاء على استخدام API إلى إزالة معظم مشكلات الفساد.

سيساعد الاحتفاظ بالبيانات مع عدد المرجع بدلاً من صفحة مختلفة في موقع البيانات وبالتالي تحسين أداء ذاكرة التخزين المؤقت.

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

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