এখনও ভালগ্রাইন্ড দ্বারা সনাক্তযোগ্য লিক সনাক্ত করা হয়েছে


154

এই ব্লকটিতে উল্লিখিত সমস্ত ফাংশনগুলি লাইব্রেরির ফাংশন। আমি কীভাবে এই স্মৃতি ফুটোটি সংশোধন করতে পারি?

এটি " এখনও পৌঁছনীয় " বিভাগের অধীনে তালিকাভুক্ত করা হয়েছে । (আরও 4 টি রয়েছে যা খুব মিল, তবে বিভিন্ন আকারের)

 630 bytes in 1 blocks are still reachable in loss record 5 of 5
    at 0x4004F1B: calloc (vg_replace_malloc.c:418)
    by 0x931CD2: _dl_new_object (dl-object.c:52)
    by 0x92DD36: _dl_map_object_from_fd (dl-load.c:972)
    by 0x92EFB6: _dl_map_object (dl-load.c:2251)
    by 0x939F1B: dl_open_worker (dl-open.c:255)
    by 0x935965: _dl_catch_error (dl-error.c:178)
    by 0x9399C5: _dl_open (dl-open.c:584)
    by 0xA64E31: do_dlopen (dl-libc.c:86)
    by 0x935965: _dl_catch_error (dl-error.c:178)
    by 0xA64FF4: __libc_dlopen_mode (dl-libc.c:47)
    by 0xAE6086: pthread_cancel_init (unwind-forcedunwind.c:53)
    by 0xAE61FC: _Unwind_ForcedUnwind (unwind-forcedunwind.c:126)

ক্যাচ: একবার আমি আমার প্রোগ্রামটি চালানোর পরে, এটি কোনও মেমরি ফাঁস দেয়নি, তবে এতে ভালগ্রাইন্ড আউটপুটে একটি অতিরিক্ত লাইন ছিল, যা আগে উপস্থিত ছিল না:

মুনম্যাপের কারণে /lib/libgcc_s-4.4.4-20100630.so.1 এ 0x5296fa0-0x52af438 এ সিমগুলি ছাড়ছে ()

যদি এই ফাঁসটি সংশোধন করা যায় না, তাহলে কি কমপক্ষে কেউ ব্যাখ্যা করতে পারেন যে মুনম্যাপ () লাইনটি ভালগ্রিন্ডকে 0 "এখনও পৌঁছনীয়" লিকের কারণ বলে?

সম্পাদনা:

এখানে একটি সর্বনিম্ন পরীক্ষার নমুনা রয়েছে:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

void *runner(void *param) {
    /* some operations ... */
    pthread_exit(NULL);
}

int n;

int main(void) {

    int i;
    pthread_t *threadIdArray;

    n=10; /* for example */

    threadIdArray = malloc((n+n-1)*sizeof(pthread_t));  

    for(i=0;i<(n+n-1);i++) {
        if( pthread_create(&threadIdArray[i],NULL,runner,NULL) != 0 ) {
            printf("Couldn't create thread %d\n",i);
            exit(1);
        }
    }


    for(i=0;i<(n+n-1);i++) {
        pthread_join(threadIdArray[i],NULL);
    }

    free(threadIdArray);

    return(0);
}

সাথে চালান:

valgrind -v --leak-check=full --show-reachable=yes ./a.out

উত্তর:


378

"মেমরি ফাঁস" সংজ্ঞায়িত করার একাধিক উপায় রয়েছে। বিশেষত, "মেমরি ফাঁস" এর দুটি প্রাথমিক সংজ্ঞা রয়েছে যা প্রোগ্রামারদের মধ্যে প্রচলিত রয়েছে।

"মেমরি ফুটো" এর প্রথম ব্যবহৃত সংজ্ঞাটি হ'ল, "মেমরি বরাদ্দ করা হয়েছিল এবং পরবর্তীকালে প্রোগ্রামটি শেষ হওয়ার আগে মুক্তি দেওয়া হয়নি।" যাইহোক, অনেক প্রোগ্রামার (যথাযথভাবে) যুক্তি দেয় যে নির্দিষ্ট সংখ্যক মেমরি ফাঁস যা এই সংজ্ঞায় ফিট করে আসলে কোনও ধরণের সমস্যা হয় না এবং তাই সত্য "মেমরি ফাঁস" হিসাবে বিবেচনা করা উচিত নয় ।

"মেমরি লিক" এর একটি তর্কসাপেক্ষে কঠোর (এবং আরো উপযোগী) সংজ্ঞা নেই, "স্মৃতি বরাদ্দ করা হয় এবং না পারেন, পরবর্তীকালে মুক্তি কারণ প্রোগ্রাম আর বরাদ্দ মেমরি ব্লক কোনো পয়েন্টার রয়েছে।" অন্য কথায়, আপনি মেমরি মুক্ত করতে পারবেন না যে আপনার আর কোনও পয়েন্টার নেই। এই জাতীয় স্মৃতিশক্তি তাই একটি "মেমরি ফুটো"। ভ্যালগ্রিন্ড "মেমরি ফাঁস" শব্দটির এই কঠোর সংজ্ঞাটি ব্যবহার করে। এটি লিকের ধরণ যা বিশেষত দীর্ঘকালীন প্রক্রিয়াগুলির জন্য উল্লেখযোগ্যভাবে গুরুত্বপূর্ণ গাদা হ্রাস পেতে পারে।

ভালগ্রিন্ডের ফুটো প্রতিবেদনের মধ্যে "এখনও পৌঁছনীয়" বিভাগটি বরাদ্দগুলিকে বোঝায় যা "মেমরি ফাঁস" এর প্রথম সংজ্ঞা অনুসারে ফিট করে। এই ব্লকগুলি মুক্ত করা হয়নি, তবে সেগুলি মুক্ত করা যেতে পারে (যদি প্রোগ্রামারটি চাইত) কারণ প্রোগ্রামটি এখনও সেই মেমরি ব্লকের দিকে নির্দেশকের খোঁজ রাখছিল।

সাধারণভাবে, "এখনও পৌঁছনীয়" ব্লকগুলি নিয়ে চিন্তা করার দরকার নেই। সত্য মেমরি ফাঁস হতে পারে এমন ধরণের সমস্যা তারা এনে দেয় না । উদাহরণস্বরূপ, "এখনও অ্যাক্সেসযোগ্য" ব্লকগুলি থেকে সাধারণভাবে গাদা ছাড়ার কোনও সম্ভাবনা নেই। কারণ এই ব্লকগুলি সাধারণত এক সময়ের বরাদ্দ থাকে, যা উল্লেখগুলি প্রক্রিয়াটির জীবদ্দশায় পুরো সময়কাল জুড়ে রাখা হয়। আপনি যখন যেতে পারেন এবং আপনার প্রোগ্রামটি সমস্ত বরাদ্দ মেমরি মুক্ত করে তা নিশ্চিত করতে পারত, অপারেটিং সিস্টেমটি প্রক্রিয়াটি শেষ হওয়ার পরে প্রক্রিয়াটির সমস্ত স্মৃতি পুনরায় দাবি জানায় যেহেতু সাধারণত এটি করা থেকে কোনও ব্যবহারিক সুবিধা নেই। এটি সত্যের সাথে বৈপরীত্য করুন মেমরি ফাঁস যা অপ্রত্যাশিতভাবে ছেড়ে দেওয়া হয়, যদি দীর্ঘ পর্যায়ে চলতে থাকে তবে কোনও প্রক্রিয়া মেমরির বাইরে চলে যেতে পারে বা প্রয়োজনের তুলনায় আরও অনেক বেশি স্মৃতি গ্রহণ করার প্রক্রিয়াটি কেবলমাত্র ঘটায়।

সমস্ত বরাদ্দের সাথে "ফ্রি" মিলছে কিনা তা নিশ্চিত হওয়া কেবলমাত্র কার্যকর হবে যদি আপনার ফাঁস সনাক্তকরণ সরঞ্জামগুলি কোন ব্লকটি "এখনও পৌঁছনীয়" (তবে ভালগ্রাইন্ড এটি করতে পারে) বা যদি আপনার অপারেটিং সিস্টেমের সমস্তটি পুনরায় দাবি না করে তবে তা নির্ধারণ করতে পারে না একটি সমাপ্তির প্রক্রিয়াটির স্মৃতি (সমস্ত প্ল্যাটফর্ম যা ভ্যালগ্রিন্ড এটি করতে পোর্ট করা হয়েছে)।


মুনম্যাপ () কী করছে যা আপনি "এখনও পৌঁছনীয়" ব্লকগুলি অদৃশ্য হয়ে যায় তা কী আপনি নজর দিতে পারেন?

3
@ ক্রাইপ্টো: এটি এমন হতে পারে যা munmapকোনও অংশীদারি অবজেক্টটি লোড করার ফলস্বরূপ অনুরোধ করা হয়েছিল। এবং ভাগ করা বস্তু দ্বারা ব্যবহৃত সমস্ত সংস্থানগুলি এটি লোড হওয়ার আগেই মুক্ত হতে পারে। এটি ব্যাখ্যা করতে পারে কেন "এখনও পৌঁছনীয়" এই munmapক্ষেত্রে মুক্তি পাচ্ছে । আমি যদিও এখানে অনুমান করছি। নিশ্চিতভাবে বলতে এখানে পর্যাপ্ত তথ্য নেই।
ড্যান মোল্ডিং

3
একটি ক্ষেত্রে যেখানে "এখনও পৌঁছনীয়" মেমরিটিকে মেমরি ফাঁস হিসাবে বিবেচনা করা যেতে পারে: ধরে নিন আপনার কাছে একটি হ্যাশ টেবিল রয়েছে যেখানে আপনি মান হিসাবে বরাদ্দ হওয়া মেমরির জন্য পয়েন্টার যুক্ত করেন। আপনি যদি টেবিলটিতে নতুন এন্ট্রি সন্নিবেশ করিয়ে রাখেন, তবে আপনার আর প্রয়োজন নেই এমনগুলি সরিয়ে ফেলেন এবং মুক্ত করবেন না, তবে অনির্দিষ্টকালের জন্য এটি বাড়তে পারে, যদি সেই স্মৃতি তাত্ত্বিকভাবে "এখনও পৌঁছনীয়" হয় তবে হিপ মেমরি ইভেন্ট ফাঁস হয়। এটি জাভা বা অন্যান্য আবর্জনা সংগ্রহ করা ভাষাগুলিতে মেমরি ফাঁসের ক্ষেত্রে।
lvella

এসটিএল দ্বারা তৈরি করা "এখনও পৌঁছনীয়" ব্লকগুলি সম্পর্কে এই উত্তরটি ভালগ্রাইন্ড এফএকিউতে দেখুন। valgrind.org/docs/manual/faq.html#faq.reports
জন পেরি

5
"অনেক প্রোগ্রামার (সঠিকভাবে) যুক্তি দেয় যে [ফাঁস স্মৃতি] আসলে সমস্যা সৃষ্টি করে না [এ] এবং তাই সত্যিকারের মেমরি ফাঁস হিসাবে বিবেচনা করা উচিত নয়" - লোল ... সেই ধরণের মেমরি ফাঁস দিয়ে একটি নেটিভ ডিএলএল তৈরি করুন এবং তারপরে জাভা বা। নেট এটি গ্রাস করুন। জাভা এবং। নেট কোনও প্রোগ্রাম চলাকালীন হাজার হাজার বার ডিএলএল লোড এবং আনলোড করুন। প্রতিবার ডিএলএল পুনরায় লোড হওয়ার পরে এটি আরও কিছুটা স্মৃতি ফাঁস হবে। দীর্ঘ চলমান প্রোগ্রামগুলি শেষ পর্যন্ত স্মৃতি থেকে সরে যাবে। এটি ডেবিয়ানের ওপেনজেডিকে রক্ষণাবেক্ষণকারীকে উন্মাদ করে তোলে। ওপেনএসএসএল মেলিং তালিকায় তিনি একই কথা বলেছেন যখন আমরা ওপেনএসএসএলের "সৌম্য" মেমরি ফাঁস নিয়ে আলোচনা করছিলাম।
jww

10

যেহেতু নীচে অজস্র পরিবার থেকে কিছু রুটিন রয়েছে (তবে আমি সেই বিশেষটিকে জানি না), আমার অনুমান যে আপনি কোনও থ্রেড জয়েন্টেবল হিসাবে চালু করেছেন যা কার্যকর করা বন্ধ করেছে।

আপনি কল না করা পর্যন্ত এই থ্রেডের প্রস্থান স্থিতির তথ্য উপলব্ধ থাকবে pthread_join। সুতরাং, প্রোগ্রামটি সমাপ্তির সময় স্মৃতিটিকে ক্ষতির রেকর্ডে রাখা হয়, তবে এটি pthread_joinঅ্যাক্সেস করার জন্য আপনি যেহেতু ব্যবহার করতে পারেন তা এখনও পৌঁছনীয় ।

যদি এই বিশ্লেষণটি সঠিক হয়, হয় এই থ্রেডগুলি বিযুক্ত করে চালু করুন, বা আপনার প্রোগ্রামটি শেষ করার আগে এগুলিতে যোগদান করুন।

সম্পাদনা করুন : আমি আপনার নমুনা প্রোগ্রামটি চালিয়েছি (কিছু স্পষ্ট সংশোধনের পরে) এবং আমার ত্রুটিগুলি নেই তবে নিম্নলিখিতগুলি রয়েছে

==18933== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 4 from 4)
--18933-- 
--18933-- used_suppression:      2 dl-hack3-cond-1
--18933-- used_suppression:      2 glibc-2.5.x-on-SUSE-10.2-(PPC)-2a

যেহেতু dl-জিনিসটি আপনি যা দেখেন তার সাথে অনেকটা সাদৃশ্যযুক্ত আমি অনুমান করি যে আপনি একটি পরিচিত সমস্যা দেখতে পাচ্ছেন যার জন্য দমন ফাইলের ক্ষেত্রে সমাধান রয়েছে valgrind। সম্ভবত আপনার সিস্টেমটি আপ টু ডেট নয় বা আপনার বিতরণ এই জিনিসগুলি বজায় রাখে না। (আমার উবুন্টু 10.4, 64 বিট)


আমি আপনার মত 0 টি ত্রুটি পাচ্ছি। "ফাঁস" সম্পর্কিত তথ্যের জন্য দয়া করে ফাঁসের সারাংশটি পরীক্ষা করে দেখুন।

@ ক্রাইপ্টো: আমি বুঝতে পারি না। তুমি বোঝাতে চাইলে আমার মতো একই দাগ আছে?
জেনস গুস্ট্ট

Used_suppression: 14 dl-hack3-cond-1 <- এটাই আমি পেয়েছি

6

আপনি কী বোঝাতে চাইছেন তা উপস্থিত হবে না still reachable

যেকোনো কিছু still reachableহয় না একটি লিক। এটি সম্পর্কে আপনার কিছু করার দরকার নেই।


24
এই ভ্যালগ্রিন্ডের সরবরাহিত পাশাপাশি অন্য প্রযুক্তিগতভাবে ভুল হিসাবে ব্যবহৃত অন্য ক্রিয়াগুলির সাথে দ্বন্দ্ব। প্রোগ্রামটি প্রস্থান করার সময় মেমরিটি "এখনও পৌঁছনীয়" এবং এইভাবে সম্ভাব্যভাবে একটি ফুটো হয়ে যায়। আপনি যদি কোনও আরটিওএস চালানোর জন্য কোডটি ডিবাগিং করে যা প্রোগ্রামটি প্রস্থান করার পরে মেমরিটি ভালভাবে পরিষ্কার করে না?
টয়মেকিরই

4
দুর্ভাগ্যক্রমে, এটি সবসময় সত্য নয়। উদাহরণস্বরূপ হারানো ফাইল বর্ণনাকারীরা মেমরি ফাঁস হিসাবে গণনা করতে পারে তবে ভ্যালগ্র্যান্ড তাদের "এখনও পৌঁছনীয়" হিসাবে শ্রেণীবদ্ধ করে, সম্ভবতঃ কারণ তাদের নির্দেশক পয়েন্টারগুলি এখনও সিস্টেম টেবিলের মধ্যে অ্যাক্সেসযোগ্য। কিন্তু ডিবাগিংয়ের উদ্দেশ্যে, আসল রোগ নির্ণয়টি একটি "মেমরি ফুটো"।
সায়ান

হারানো ফাইল বর্ণনাকারী সংজ্ঞা অনুসারে মেমরি ফাঁস হয় না । আপনি কি হারিয়ে যাওয়া FILEপয়েন্টার সম্পর্কে কথা বলছেন ?
রাশিয়ান

6

এখানে "এখনও পৌঁছনীয়" এর যথাযথ ব্যাখ্যা দেওয়া হল:

"এখনও পৌঁছনীয়" হ'ল বিশ্বব্যাপী এবং স্ট্যাটিক-স্থানীয় ভেরিয়েবলগুলিকে নির্ধারিত ফাঁস। যেহেতু ভালগ্রাইন্ড গ্লোবাল এবং স্ট্যাটিক ভেরিয়েবলগুলি ট্র্যাক করে এটি মেমরির বরাদ্দগুলি বাদ দিতে পারে যা "একবার এবং ভুলে যাও" বরাদ্দ করা হয়। গ্লোবাল ভেরিয়েবল একবার বরাদ্দ দেয় এবং কখনও বরাদ্দ দেয় নি যে বরাদ্দ সাধারণত অনির্দিষ্টকালের জন্য বৃদ্ধি পায় না এই অর্থে "ফুটো" নয়। এটি এখনও কঠোর অর্থে ফাঁস, তবে আপনি পেডেন্টিক না হলে সাধারণত এড়ানো যায়।

স্থানীয় ভেরিয়েবলগুলি বরাদ্দ দেওয়া হয় এবং নিখরচায় নয় প্রায় সবসময় ফাঁস হয়।

এখানে একটি উদাহরণ

int foo(void)
{
    static char *working_buf = NULL;
    char *temp_buf;
    if (!working_buf) {
         working_buf = (char *) malloc(16 * 1024);
    }
    temp_buf = (char *) malloc(5 * 1024);

    ....
    ....
    ....

}

ভ্যালগ্রাইন্ড ওয়ার্কিং_বুফকে "এখনও পৌঁছনীয় - 16 কে" এবং টেম্প_বুফকে "অবশ্যই হারিয়েছে - 5 কে" হিসাবে প্রতিবেদন করবে।


-1

ভবিষ্যতের পাঠকদের জন্য, "স্টিল রিচ্যাবল" এর অর্থ হতে পারে আপনি কোনও ফাইলের মতো কিছু বন্ধ করতে ভুলে গেছেন। যদিও মূল প্রশ্নটিতে এটি মনে হয় না, আপনি সর্বদা এটি নিশ্চিত করেছেন।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.