سي العمومية:التصحيح تسرب الذاكرة:كيفية تفسير إخراج mtrace()

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

  •  03-07-2019
  •  | 
  •  

سؤال

أنا أحاول تصحيح مشكلة تسرب الذاكرة.أنا باستخدام mtrace() للحصول على malloc/مجانا/realloc أثر.لقد ركض بلدي prog و الآن ضخمة ملف السجل.حتى الآن جيد جدا.ولكن لدي مشاكل في تفسير الملف.ننظر في هذه السطور:

@ /usr/java/ibm-java2-x86_64-50/jre/bin/libj9prt23.so:[0x2b270a384a34] + 0x1502570 0x68
@ /usr/java/ibm-java2-x86_64-50/jre/bin/libj9prt23.so:[0x2b270a384a34] + 0x1502620 0x30
@ /usr/java/ibm-java2-x86_64-50/jre/bin/libj9prt23.so:[0x2b270a384a34] + 0x2aaab43a1700 0xa80
@ /usr/java/ibm-java2-x86_64-50/jre/bin/libj9prt23.so:[0x2b270a384a34] + 0x1501460 0xa64

الغريب في هذا هو أن مكالمة واحدة (نفس عنوان المرسل) هو المسؤول عن 4 المخصصات.

حتى غريب:

@ /usr/java/ibm-java2-x86_64-50/jre/bin/libj9prt23.so:[0x2b270a384a34] + 0x2aaab43a1700 0xa2c
…
@ /usr/java/ibm-java2-x86_64-50/jre/bin/libj9prt23.so:[0x2b270a384a34] + 0x2aaab43a1700 0xa80

بين هذين الخطين كتلة 0x2aaab43a1700 لم يتم تحريرها.

لا أحد يعرف كيف تفسر هذا ؟ كيف يمكن للمرء الاتصال النتيجة في 4 المخصصات?وكيف يمكن أن malloc العودة عنوان التي تم تخصيصها بالفعل سابقا ؟

تحرير 2008/09/30:السيناريو لتحليل mtrace() الإخراج التي تقدمها سي العمومية (mtrace.pl) ليس من أي مساعدة هنا.فإنه سوف أقول فقط:الوك 0x2aaab43a1700 مكررة.ولكن كيف يمكن أن يحدث هذا ؟

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

المحلول

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

هنا هو مثال على ذلك في ج:

void *allocate (void)
{
  return (malloc(1000));
}

int main()
{
  mtrace();
  allocate();
  allocate();
}

الإخراج من mtrace هو:

Memory not freed:
-----------------
           Address     Size     Caller
0x0000000000601460    0x3e8  at 0x4004f6
0x0000000000601850    0x3e8  at 0x4004f6

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

تجميع مع تصحيحها الأعلام (-g) هي مفيدة إذا كنت يمكن أن:

Memory not freed:
-----------------
           Address     Size     Caller
0x0000000000601460    0x3e8  at /home/andrjohn/development/playground/test.c:6
0x0000000000601850    0x3e8  at /home/andrjohn/development/playground/test.c:6

نصائح أخرى

أنت تبحث في الانتاج المباشر من mtrace التي هي مربكة للغاية و غير متوقع.لحسن الحظ, هناك perl (يسمى mtrace في سي العمومية-utils) التي يمكن بسهولة جدا أن يساعد تحليل من هذا الناتج.

تجميع الخاص بك بناء مع التصحيح على المدى mtrace مثل:

$ gcc -g -o test test.c
$ MALLOC_TRACE=mtrace.out ./test
$ mtrace test mtrace.out

Memory not freed:
-----------------
   Address     Size     Caller
0x094d9378    0x400  at test.c:6

الإخراج يجب أن يكون الكثير أسهل للهضم.

أحد التفسيرات المحتملة هو أن نفس وظيفة تخصيص مختلفة الأحجام العازلة?أحد الأمثلة على ذلك هو strdup.

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

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

حاول تشغيل التطبيق الخاص بك تحت valgrind.قد تعطيك نظرة أفضل عن ما هو في الواقع يجري تسريبه.

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