سؤال

هذا افتراضي بعض الشيء ومبسط إلى حد كبير ولكن ...

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

الهدف هو التأكد من أنها لا يمكن أن تسبب تسربًا للذاكرة عن طريق تسجيل جميع mallocs (وما شابه ذلك) ثم تحرير كل شيء بعد خروج الوظيفة.

هل هذا ممكن؟هل هذا عملي؟

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

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

المحلول

لم تحدد نظام التشغيل أو البيئة، فهذه الإجابة تفترض Linux وglibc وC.

يمكنك ضبط __malloc_hook و__free_hook و__realloc_hook للإشارة إلى الوظائف التي سيتم استدعاؤها من malloc() وrealloc() وfree() على التوالي.توجد صفحة __malloc_hook تعرض النماذج الأولية.يمكنك إضافة تخصيصات المسار في هذه الخطافات، ثم العودة للسماح لـ glibc بالتعامل مع تخصيص/إلغاء تخصيص الذاكرة.

يبدو أنك تريد تحرير أي عمليات تخصيص مباشرة عند عودة وظيفة الطرف الثالث.هناك طرق لجعل gcc يقوم تلقائيًا بإدراج المكالمات عند كل مدخل للوظيفة والخروج منها باستخدام -finstrument-functions، لكنني أعتقد أن هذا سيكون غير لائق لما تحاول القيام به.هل يمكن أن يكون لديك رمز خاص بك يستدعي وظيفة في مكتبة تتبع الذاكرة الخاصة بك بعد استدعاء إحدى وظائف الطرف الثالث هذه؟يمكنك بعد ذلك التحقق مما إذا كانت هناك أي تخصيصات لم تحررها وظيفة الجهة الخارجية بالفعل.

نصائح أخرى

أولا، عليك توفير نقاط الدخول ل malloc() و free() والأصدقاء.نظرًا لأن هذا الرمز تم تجميعه بالفعل (أليس كذلك؟) فلا يمكنك الاعتماد عليه #define لإعادة التوجيه.

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

أسرع طريقة تنطوي على لا يوجد تسجيل على الإطلاق. إذا كانت كمية الذاكرة التي يستخدمونها محدودة، فلماذا لا يتم تخصيص كل "الكومة" التي سيحتاجون إليها مسبقًا وكتابة مُخصص للخروج منها؟وبعد ذلك، قم بتحرير "الكومة" بأكملها، وبذلك تكون قد انتهيت!يمكنك توسيع هذه الفكرة لتشمل أكوامًا متعددة إذا كانت أكثر تعقيدًا من ذلك.

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

هل هو عملي؟أعتقد ذلك، طالما أن السرعة مقبولة.

يمكنك تشغيل وظائف الطرف الثالث في عملية منفصلة وإغلاق العملية عند الانتهاء من استخدام المكتبة.

قد يكون الحل الأفضل من محاولة تسجيل mallocs هو وضع الحماية للوظائف عند استدعائها - ومنحها إمكانية الوصول إلى جزء ثابت من الذاكرة ثم تحرير هذا الجزء عند الانتهاء من تشغيل الوظيفة.

يمكن أن يكون الاستخدام غير المحدود وغير الكفء للذاكرة ضارًا تمامًا مثل التعليمات البرمجية الضارة.

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

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

ومع ذلك، إذا كانت مكتبة الطرف الثالث الخاصة بك تحتوي على تخصيصات واسعة النطاق، فمن غير العملي تتبع ذلك عبر التسجيل.إذا كنت تعمل في بيئة Windows، فإنني أقترح استخدام أداة مثل Purify[1] أو BoundsChecker[2] التي من المفترض أن تكون قادرة على اكتشاف التسريبات في مكتبات الطرف الثالث لديك.يجب أن يدفع الاستثمار في الأداة تكاليفه في الوقت الذي يتم توفيره.

[1]: http://www-01.ibm.com/software/awdtools/purify/ تنقية

[2]: http://www.compuware.com/products/devpartner/visualc.htm BoundsChecker

نظرًا لأنك قلق بشأن تسرب الذاكرة وتتحدث عن malloc/free، أفترض أنك في لغة C.أفترض أيضًا بناءً على سؤالك أنه لا يمكنك الوصول إلى الكود المصدري لمكتبة الطرف الثالث.

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

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

إذا كنت فقيرًا جدًا ولا تستطيع استخدام Purify، فجرّب Valgrind.لقد أصبح الأمر أفضل بكثير مما كان عليه قبل 6 سنوات وأسهل بكثير الغوص فيه من عملية التنقية.

يوفر Microsoft Windows (استخدم SUA إذا كنت بحاجة إلى POSIX)، من المحتمل جدًا أن تكون البنية التحتية الأكثر تقدمًا للكومة + (واجهة برمجة التطبيقات الأخرى المعروفة باستخدام الكومة) لأي نظام تشغيل شحن اليوم.

تعد خطافات التصحيح __malloc() وواجهات تصحيح أخطاء CRT المرتبطة بها جيدة للحالات التي يكون لديك فيها الكود المصدري للاختبارات، ومع ذلك، فإنها غالبًا ما تفوت عمليات التخصيص بواسطة المكتبات القياسية أو التعليمات البرمجية الأخرى المرتبطة.وهذا أمر متوقع نظرًا لأنها البنية الأساسية لتصحيح أخطاء كومة Visual Studio.

com.gflags عبارة عن مجموعة شاملة ومفصلة للغاية من إمكانيات تصحيح الأخطاء التي تم تضمينها مع Windows لسنوات عديدة.وجود وظائف متقدمة لحالات الاستخدام المصدر والثنائي فقط (حيث إنها البنية التحتية لتصحيح أخطاء نظام التشغيل).

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

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

ملحوظة هناك وضعان؛

  1. الوضع 1، umdh {-p:Process-id|-pn:ProcessName} [-f:اسم الملف] [-g]
  2. الوضع 2، umdh [-d] {File1} [File2] [-f:اسم الملف]

    لا أعرف ما هو الجنون الذي أصاب المطور الذي اختار التبديل بين محدد الوسيطة -p:foo والترتيب العاري للوسيطات ولكن قد يكون الأمر مربكًا بعض الشيء.

يعمل تصحيح الأخطاء sdk مع عدد من الأدوات الأخرى، com.memsnap هي أداة تركز على ما يبدو على تسرب الذاكرة وما شابه، لكنني لم أستخدمها، فقد يختلف عدد الأميال الخاصة بك.

قم بتنفيذ gflags بدون وسائط لوضع واجهة المستخدم، +arg's و/args مختلف "طرق" الاستخدام أيضًا.

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