سؤال

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

char szTest [1] = "";

for (i = 0; i < 100; i ++) {

    strcat (szTest, "hi");
}

السؤال 1: هل أي طريقة ، يمكنني صنع Boodschecker للكشف عن هذا؟

السؤال الثاني: هل أي أداة أخرى يمكنها اكتشاف مثل هذه المشكلات؟

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

المحلول

جربته في Devpartner (MSVC6.6) (Devpartner 7.2.0.372)

أؤكد سلوكك المرصود. أحصل على انتهاك للوصول بعد حوالي 63 تمريرة من الحلقة.

ما الذي يجب أن يقوله compuware حول هذه القضية؟

cppcheck سوف يكتشف هذه المسألة.

نصائح أخرى

يتمثل أحد الخيارات في حظر استخدام وظائف السلسلة التي لا تحتوي على معلومات حول المخزن المؤقت للوجهة. يمكن أن تكون مجموعة من وحدات الماكرو مثل ما يلي في رأس مشمل عالميًا مفيدة:

#define strcpy  strcpy_is_banned_use_strlcpy
#define strcat  strcat_is_banned_use_strlcat
#define strncpy strncpy_is_banned_use_strlcpy
#define strncat strncat_is_banned_use_strlcat
#define sprintf sprintf_is_banned_use_snprintf

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

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

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

تعديل: انا كنت الحق في فالغريند, ، ولكن هناك بعض الأمل:

لسوء الحظ ، لا يقوم Memcheck بالتحقق من المصفوفات الثابتة أو المكدس. نود ذلك ، ولكن ليس من الممكن أن نفعل بطريقة معقولة تتناسب مع كيفية عمل Memcheck. آسف.

ومع ذلك ، يمكن للأداة التجريبية ptrcheck اكتشاف أخطاء مثل هذه. قم بتشغيل Valgrind مع --tool=exp-ptrcheck خيار لتجربته ، ولكن احذر من أنه ليس قويًا مثل Memcheck.

لم أستخدم ptrcheck.

قد تجد أن المترجم الخاص بك يمكن أن يساعد. على سبيل المثال ، في Visual Studio 2008 ، تحقق من خصائص المشروع - C/C ++ - صفحة توليد الكود. هناك خيار "فحص الأمان العازلة".

سيكون تخميني أنه يحتفظ بقليل من الذاكرة الإضافية ويكتب تسلسلًا معروفًا هناك. إذا تم تعديل هذا التسلسل ، فإنه يفترض تجاوز المخزن المؤقت. لست متأكدًا ، على الرغم من ذلك - أتذكر قراءة هذا في مكان ما ، لكنني لا أتذكر على وجه اليقين ما إذا كان الأمر يتعلق بـ VC ++.

بالنظر إلى أنك قمت بتمييز هذا C ++ ، فلماذا استخدم مؤشرًا على الإطلاق؟

std::stringstream test;
std::fill_n(std::ostream_iterator<std::string>(test), 100, "hi");

إذا قمت بتمكين مفتاح برمجيات البرمجيات /RTCS, ، قد يساعد في القبض على مشاكل مثل هذا. مع تشغيل هذا المفتاح ، تسبب الاختبار في انتهاك للوصول عند تشغيل strcat فقط مرة واحدة.

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

بديل: مدقق سلامة الذاكرة. أعتقد أنها ستتعامل مع هذه الحالة.

كانت المشكلة أنه افتراضيًا ، لم يتم تمكين نظام التحقق من صحة API ، والرسائل التي كنت مهتمًا بها من هناك.

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

النتائج: 100 رسالة حول تجاوز الكتابة إلى متغير محلي ، و 99 رسالة حول سلسلة الوجهة التي لم يتم إنهاءها. من الناحية الفنية ، فإن هذه الرسالة الثانية ليست صحيحة ، ولكن Boodschecker يبحث فقط عن الإنهاء الفارغ داخل حدود سلسلة الوجهة نفسها ، وبعد مكالمة Strcat الأولى ، لم يعد يحتوي على بايت صفر داخل حدوده.

إخلاء المسئولية: أعمل في Microfocus كمطور يعمل على BoundSchecker.

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