[Powered by Google Translate] [Valgrind]
[نيت Hardison، جامعة هارفارد]
هذا هو CS50، CS50.TV]
بعض الخلل الأكثر صعوبة في برامج C
تأتي من سوء إدارة الذاكرة.
هناك عدد كبير من الطرق لالمسمار الامور،
بما في ذلك تخصيص مبلغ الخطأ من الذاكرة،
النسيان لتهيئة المتغيرات،
الكتابة قبل أو بعد نهاية المخزن المؤقت،
وتحرير الذاكرة الاحتفاظ مرات متعددة.
الأعراض تتراوح من حوادث متقطعة
إلى قيم الكتابة في ظروف غامضة،
في كثير من الأحيان في أماكن وأوقات بعيدة كل البعد عن الخطأ الأصلي.
تتبع المشكلة الملاحظ عودة إلى السبب الجذري الأساسي
يمكن أن يكون تحديا،
لكن لحسن الحظ هناك برنامج يسمى مفيدة Valgrind
يمكن أن تفعل الكثير للمساعدة.
>> تشغيل برنامج لتمكين تحت Valgrind
فحص واسعة النطاق تخصيص الذاكرة والوصول إلى كومة.
عندما Valgrind كشف مشكلة، فإنه يوفر لك على الفور،
المعلومات المباشرة التي تسمح لك ل
أكثر سهولة العثور وإصلاح المشكلة.
Valgrind أيضا تقارير عن مشاكل الذاكرة أقل فتكا،
مثل التسرب في الذاكرة، وتخصيص ذاكرة الكومة،
والنسيان اطلاق سراحه.
لدينا مثل مترجم، ضجيج، في المصحح لدينا، GDB،
Valgrind هي البرمجيات الحرة، وتثبيته على الجهاز.
Valgrind يعمل على ثنائي قابل للالخاص بك،
ليس لديك. ج أو شفرة المصدر ملفات ساعة،
لذا يجب التأكد كنت قد جمعت نسخة ما يصل إلى تاريخ البرنامج
استخدام ضجيج أو تقديم.
ثم، يمكن تشغيل البرنامج تحت Valgrind يكون
بسيطة مثل التقديم فقط الأمر مع برنامج القياسية Valgrind كلمة،
الذي يبدأ Valgrind ويعمل البرنامج داخل منه.
عند بدء، لا Valgrind بعض معقدة
القولبة لتكوين الملف التنفيذي للشيكات الذاكرة،
لذلك يمكن أن يستغرق قليلا للحصول على قائمة وعاملة.
سيقوم البرنامج ثم تنفيذ عادة، سواء كان ذلك ببطء أكثر بكثير،
وعندما ينتهي، وسوف Valgrind طباعة ملخص استخدام الذاكرة.
إذا سارت الامور بشكل جيد، وسوف ننظر بشيء من هذا القبيل:
في هذه الحالة، / clean_program
هو المسار إلى برنامج I تريد تشغيله.
وعلى الرغم من هذا واحد لا يأخذ أية وسائط،
إذا فعلت يهمني تك منهم فقط إلى نهاية الأمر على النحو المعتاد.
برنامج النظيفة هو مجرد سخيفة قليلا برنامج أنا خلقت
أن يخصص مساحة لكتلة من رجات على كومة،
وضع بعض القيم داخل منهم، وتفرج عن كتلة كاملة.
هذا هو ما كنت اطلاق النار ل، وعدم وجود أخطاء التسريبات لا.
>> آخر متري المهم هو العدد الإجمالي من وحدات البايت المخصصة.
وفقا للبرنامج، إذا المخصصات الخاصة بك في ميغا بايت أو أعلى،
ربما كنت تريد ان تفعل شيئا خاطئا.
هل أنت تخزين دون داع مكررة؟
هل تستخدم لتخزين الكومة، عندما كان من الأفضل استخدام المكدس؟
لذلك، يمكن أن تكون أخطاء الذاكرة الشر حقا.
هم أكثر علنية تتسبب في حوادث مذهلة،
لكن حتى ذلك الحين يمكن أن يكون لا يزال من الصعب تحديد
ما أدى إلى تحطم تماما.
أكثر دهاء، وهو برنامج مع خطأ الذاكرة
يمكن تجميع تزال نظيفة
ويبدو أن لا يزال للعمل بشكل صحيح
لأن تدار لك للحصول على محظوظا أكثر من مرة.
بعد عدة "النتائج الناجحة"
قد تعتقد أن مجرد حادث هو مجرد صدفة للكمبيوتر،
لكن الكمبيوتر لا يخطئ.
>> يمكن تشغيل Valgrind تساعدك على تعقب سبب أخطاء الذاكرة مرئية
وكذلك إيجاد الأخطاء الكامنة كنت لا تعرف عن بعد حتى.
في كل مرة Valgrind كشف مشكلة، فإنه يطبع المعلومات حول ما لوحظ.
كل عنصر هو مقتضب إلى حد ما -
خط مصدر التعليمة المخالف، ما المسألة،
والقليل من المعلومات حول الذاكرة المشتركة -
ولكن في كثير من الأحيان أنها معلومات كافية لتوجيه انتباهكم الى المكان الصحيح.
هنا مثال على Valgrind يعمل على برنامج عربات التي تجرها الدواب
التي لا أحد غير صالحة للقراءة من الذاكرة الكومة.
لا نرى أخطاء أو تحذيرات في تجميع.
اه أوه، الملخص خطأ يقول ان هناك اثنين من الأخطاء -
من عقدين من يقرأ غير صالحة حجم 4 - بايت، وهذا هو.
كل سيئة يقرأ وقعت في الوظيفة الرئيسية للinvalid_read.c،
أول على خط 16 والثاني على خط 19.
دعونا ننظر في التعليمات البرمجية.
يبدو أن المكالمة الأولى ليحاول printf لقراءة واحدة الباحث بعد نهاية كتلة ذاكرتنا.
إذا نظرنا إلى الوراء في الناتج Valgrind ل،
ونحن نرى أن Valgrind قال لنا بالضبط.
عنوان نحاول قراءة يبدأ 0 بايت
بعد نهاية كتلة من حجم 16 بايت -
32-4 بت رجات أننا المخصصة.
وهذا هو، عنوان كنا نحاول قراءة يبدأ الحق في نهاية كتلة لدينا،
تماما كما نرى في دعوتنا printf سيئة.
الآن، قد لا يبدو غير صالح قراءة من هذا القبيل كبيرة من التوصل الى اتفاق،
ولكن إذا كنت تستخدم هذه البيانات للسيطرة على تدفق البرنامج -
على سبيل المثال، كجزء من بيان أو إذا حلقة -
ثم يمكن أن تسير الأمور سيئة بصمت.
مشاهدة كيف يمكنني تشغيل برنامج invalid_read
ولا شيء خارج عن المألوف يحدث.
مخيف، أليس كذلك؟
>> الآن، دعونا ننظر في بعض أنواع أكثر من الأخطاء التي قد تواجهها في التعليمات البرمجية،
وسنرى كيف Valgrind يكشف لهم.
رأينا مجرد مثال لinvalid_read،
حتى الآن دعونا تحقق من وinvalid_write.
مرة أخرى، أية أخطاء أو تحذيرات في تجميع.
حسنا، Valgrind يقول ان هناك اثنين من الأخطاء في هذا البرنامج -
وinvalid_write وinvalid_read ملف.
دعونا تحقق من هذا الرمز.
يبدو أننا قد حصلت على مثيل من التوابع strlen الكلاسيكية بالإضافة إلى علة واحدة.
رمز لا malloc على بايت إضافية من الفضاء
للحرف / 0،
لذلك عندما ذهبت إلى شارع نسخة كتابتها في ssubstrlen "الصخور CS50!"
كتب عليه 1 بايت بعد نهاية كتلة لدينا.
ويأتي invalid_read عندما نتخذ دعوتنا إلى printf.
Printf ينتهي القراءة ذاكرة غير صالحة عندما يقرأ / 0 حرف
كما يبدو في نهاية هذه السلسلة E انها الطباعة.
ولكن لا شيء من هذا نجا Valgrind.
ونحن نرى أنه اشتعلت invalid_write كجزء من نسخة شارع
على خط 11 من الرئيسي، وinvalid_read هو جزء لل printf.
الصخرة، Valgrind.
مرة أخرى، وهذا قد لا يبدو مثل صفقة كبيرة.
يمكننا تشغيل هذا البرنامج مرارا وتكرارا خارج Valgrind
ولم تر اي اعراض الخطأ.
>> ومع ذلك، دعونا ننظر في اختلاف طفيف من هذا أن نرى
كيف يمكن الحصول على أشياء سيئة حقا.
لذلك، منح، ونحن استغلال الأشياء أكثر من بت واحد فقط في هذا القانون.
نحن فقط تخصيص مساحة على كومة لسلسلتين
طول CS50 الصخور،
هذه المرة، تذكر / 0 حرف.
ولكن بعد ذلك نلقي في سلسلة طويلة فائقة في كتلة الذاكرة
S أن يتم الإشارة إلى.
ما تأثير ذلك على وكتلة الذاكرة الذي يشير إلى T؟
حسنا، إذا كان T نقطة إلى ذاكرة هذا المتاخمة لمجرد S،
وصلت للتو بعد ذلك،
ثم قد كتبنا على جزء من T.
دعونا تشغيل هذا الرمز.
ننظر إلى ما حدث.
يبدو أننا السلاسل المخزنة في كومة كتل لدينا على حد سواء أن تطبع بشكل صحيح.
لا شيء يبدو خاطئا على الإطلاق.
ومع ذلك، دعونا نعود إلى نظامنا و
تعليق خارج السطر حيث أننا نسخ CS50 الصخور
إلى كتلة الذاكرة الثانية، المشار إليه بواسطة ر.
الآن، عندما كنا تشغيل هذا الرمز يجب علينا
إلا أن نرى محتويات كتلة الذاكرة الأولى طباعة.
قف، على الرغم من فعلنا لا شارع نسخة
أي شخصية في كتلة كومة الثانية، وأشار إلى واحد من T،
نحصل على طباعة.
والواقع أن سلسلة محشوة نحن في كتلة الأولى لنا
اجتاحت كتلة الأولى وإلى كتلة الثاني،
مما يجعل كل شيء يبدو طبيعيا.
Valgrind، رغم ذلك، يقول لنا القصة الحقيقية.
هناك نذهب.
كل هذه غير صالحة يقرأ ويكتب.
>> دعونا ننظر إلى مثال من نوع آخر من الخطأ.
هنا نفعل شيئا مؤسفا.
نحن انتزاع مساحة لكثافة العمليات على كومة،
ونحن تهيئة مؤشر كثافة العمليات - ع - للإشارة إلى أن الفضاء.
ومع ذلك، في حين تتم تهيئة مؤشر لدينا،
البيانات التي تشير إلى انها مجرد وأيا كان هو غير المرغوب فيه في هذا الجزء من الكومة.
لذلك عندما نقوم بتحميل هذه البيانات إلى ط كثافة العمليات،
نحن تهيئة تقنيا ط،
ولكننا نفعل ذلك مع البيانات غير المرغوب فيه.
الدعوة إلى تأكيد، والذي هو في متناول يدي ماكرو التصحيح
المعرفة في مكتبة تأكيد اسم على مسمى،
سوف إحباط البرنامج إذا فشل الاختبار حالتها.
وهذا هو، إذا كنت غير 0.
اعتمادا على ما ورد في مساحة الكومة، المشار إليه بواسطة ع،
هذا البرنامج قد يعملون أحيانا وتفشل في أحيان أخرى.
اذا كان يعمل، ونحن مجرد الحصول على محظوظ.
فإن المترجم لا يمسك هذا الخطأ، ولكن إرادة Valgrind بالتأكيد.
هناك نرى الخطأ الناجمة عن استخدامنا للبيانات التي غير المرغوب فيه.
>> عند تخصيص ذاكرة الكومة ولكن لا إلغاء تخصيص ذلك أو تحريرها،
ويسمى ذلك تسرب.
برنامج صغير للم يدم طويلا، والتي يتم تنفيذها على الفور مخارج،
تسريبات غير مؤذية إلى حد ما،
ولكن لمشروع من الحجم الكبير و / أو طول العمر،
حتى يمكن تسرب صغير المركب إلى هناك شيئا كبيرا.
لCS50، ونحن لا نتوقع منكم أن
رعاية تحرير كل من ذاكرة الكومة التي تخصص،
حيث أننا نريد لك لبناء المهارات اللازمة لمعالجة بشكل صحيح عملية يدوية
المطلوبة من قبل C.
للقيام بذلك، يجب أن يكون لديك برنامج دقيق
واحد الى واحد المراسلات بين malloc ومكالمات مجانية.
لحسن الحظ، يمكن أن تساعدك على Valgrind مع تسرب الذاكرة أيضا.
هنا برنامج راشح دعا leak.c أن يخصص
الفضاء على كومة، ويكتب إلى ذلك، ولكن لا سراحه.
نحن تجميع مع تقديم وتشغيله تحت Valgrind،
ونحن نرى أنه في حين لدينا أي أخطاء الذاكرة،
نحن لديك واحدة تسرب.
هناك 16 بايت خسر بالتأكيد،
وهذا يعني أن مؤشر إلى أن الذاكرة ليست في نطاق البرنامج عندما خرجت.
الآن، Valgrind لا يعطينا طن من المعلومات حول تسرب،
ولكن إذا اتبعنا هذه المذكرة أنه يعطي قليلا إلى أسفل نحو الجزء السفلي من تقريرها
إلى إعادة تشغيل مع - تسرب تسجيل الوصول الكامل =
لمعرفة التفاصيل الكاملة لتسرب الذاكرة،
سوف نحصل على مزيد من المعلومات.
الآن، في الملخص الكومة،
Valgrind يخبرنا في البداية حيث تم تخصيص الذاكرة التي فقدت.
تماما كما نعرف من يبحث في التعليمات البرمجية المصدر،
Valgrind يخبرنا أننا تسريب الذاكرة
تخصيص مع استدعاء malloc على خط 8 من leak.c
وتتمثل المهمة الرئيسية في.
أنيق جدا.
>> Valgrind يصنف التسريبات باستخدام هذه المصطلحات:
خسر بالتأكيد - وهذا هو كومة الذاكرة المخصصة
لبرنامج الذي لم يعد لديه المؤشر.
Valgrind يعرف أن كان لديك مرة واحدة ولكن المؤشر فقد منذ أثره.
وتسربت بالتأكيد هذه الذاكرة.
فقدت بشكل غير مباشر - وهذا هو كومة الذاكرة المخصصة
التي مؤشرات فقط لأنه أيضا يتم فقدان.
على سبيل المثال، إذا كنت فقدت المؤشر إلى العقدة الأولى من قائمة مرتبطة،
هكذا تكون العقدة الأولى نفسها فقدت بالتأكيد،
بينما سيتم عقد أي لاحقة خسر بشكل غير مباشر.
فقدت ربما - وهذا هو كومة الذاكرة المخصصة
الذي يمكن أن يكون متأكدا Valgrind ما إذا كان هناك مؤشر أم لا.
لا تزال قابلة للوصول هو كومة الذاكرة المخصصة
لبرنامج الذي لا يزال لديه مؤشر على الخروج،
وهو ما يعني عادة أن نقاط العالمي المتغير لذلك.
للتحقق من هذه التسريبات، سيكون لديك أيضا لتشمل الخيار
- لا تزال قابلة للوصول = نعم
في الاحتجاج بك من Valgrind.
>> قد تتطلب هذه الحالات المختلفة استراتيجيات مختلفة لتنظيف عنها،
ولكن ينبغي أن يتم القضاء على التسريبات.
لسوء الحظ، يمكن إصلاح التسريبات يكون من الصعب القيام به،
منذ أن المكالمات غير صحيحة لتحرير تفجير البرنامج.
على سبيل المثال، إذا نظرنا إلى invalid_free.c،
نرى مثالا على deallocation الذاكرة السيئة.
ماذا يجب أن تكون مكالمة واحدة لتحرير المبنى كله
من الذاكرة المشار إليه بواسطة int_block،
بدلا من ذلك أصبح محاولة لتحرير كل قسم الباحث الحجم
من الذاكرة بشكل فردي.
سوف تفشل هذه كارثي.
بوم! ما خطأ.
هذا هو بالتأكيد ليست جيدة.
إذا كنت عالقا مع هذا النوع من الخطأ، رغم ذلك، وكنت لا تعرف أن ننظر فيها،
يرتد على صديق جديد افضل ما لديكم.
هل تفكر في ذلك - Valgrind.
Valgrind، كما هو الحال دائما، يعرف بالضبط ما يعود.
التهم alloc والحرة لا تصل المباراة.
لقد حصلت على 1 و 4 alloc يحرر.
ويخبرنا أيضا Valgrind حيث أول مكالمة مجانية سيئة -
واحد الذي تسبب في تضخم - قادم من -
السطر 16.
كما ترون، ومكالمات سيئة لتحرير هي سيئة حقا،
لذلك نحن ننصح السماح تسرب البرنامج الخاص بك
بينما كنت تعمل على الحصول على وظائف الصحيح.
البدء في البحث عن التسريبات إلا بعد البرنامج يعمل بشكل صحيح،
دون أية أخطاء أخرى.
>> وهذا كل ما لدينا لهذا الفيديو.
الآن ماذا تنتظر؟
تذهب تشغيل Valgrind على البرامج الخاصة بك الآن.
اسمي نيت Hardison. هذا هو CS50. [CS50.TV]