আমি কেন সি ম্যালোক দৃser় ব্যর্থতা পাব?


86

তাই আমি একটি OpenCL বাস্তবায়ন বিরুদ্ধে বেঞ্চমার্ক করতে পারেন আমি একটি ডিভাইড এবং জয় করো বহুপদী অ্যালগরিদম বাস্তবায়ন, কিন্তু আমি না পেতে পারেন mallocকাজ। আমি যখন প্রোগ্রামটি চালাচ্ছি, এটি কিছু গুছা বরাদ্দ দেয়, কিছু জিনিস পরীক্ষা করে, তারপরে size/2অ্যালগরিদমে প্রেরণ করে । তারপরে যখন আমি mallocআবার লাইনটি আঘাত করি তখন এটি থুতু ফেলে:

malloc.c:3096: sYSMALLOc: Assertion `(old_top == (((mbinptr) (((char *) &((av)->bins[((1) - 1) * 2])) - __builtin_offsetof (struct malloc_chunk, fd)))) && old_size == 0) || ((unsigned long) (old_size) >= (unsigned long)((((__builtin_offsetof (struct malloc_chunk, fd_nextsize))+((2 * (sizeof(size_t))) - 1)) & ~((2 * (sizeof(size_t))) - 1))) && ((old_top)->size & 0x1) && ((unsigned long)old_end & pagemask) == 0)' failed.
Aborted

প্রশ্নে লাইনটি হ'ল:

আমি একটি দিয়ে আকার পরীক্ষা করেছি fprintfএবং এটি একটি ধনাত্মক পূর্ণসংখ্যার (সাধারণত সেই সময়ে 50)। আমি mallocপাশাপাশি একটি সরল নম্বর দিয়ে কল করার চেষ্টা করেছি এবং তবুও ত্রুটিটি পেয়েছি। আমি যা চলছে তাতে আমি কেবল স্ট্যাম্পড আছি, এবং গুগলের কাছ থেকে আমি এখনও খুঁজে পাইনি যে কোনও কিছুই সহায়ক নয়।

কোন ধারণা কি চলছে? আমি যদি একটি নতুন সংস্থার সংকলক ত্রুটি হয় তার ক্ষেত্রে কীভাবে এটি একটি নতুন জিসিসি সংকলন করব তা নির্ধারণ করার চেষ্টা করছি, তবে আমি সত্যিই সন্দেহ করি।


আমি সন্দেহ করি সমস্যাটি আসলে তার আগে একটি লাইন is সম্ভবত একটি ডাবল ফ্রি?
মিচ গম

প্রোগ্রামের তৃতীয় লাইন: ইনট * মাল্ট (ইনট সাইজ, ইনট * এ, ইনট * বি) {ইনট * আউট, আই, জে, * টিএমপি 1, * টিএমপি 2, * টিএমপি 3, * টিএমপিএ 1, * টিএমপিএ 2, * টিএমপিবি 1, * টিএমপিবি 2 , d, * রেস 1, * রেজ 2; fprintf (stdout, "আকার:% d \ n", আকার); আউট = (ইনট *) ম্যালোক (সাইজ অফ (ইনট) * সাইজ * 2);
ক্রিস

উত্তর:


100

99.9% সম্ভবত আপনি মেমোরিটিকে দূষিত করেছেন (সম্ভবত বাফারকে অতিরিক্ত বা প্রবাহিত করেছেন, মুক্ত হওয়ার পরে একটি পয়েন্টারকে লিখেছিলেন, একই পয়েন্টারে দুবার বিনামূল্যে বলা হয় ইত্যাদি)

আপনার প্রোগ্রামটি কোথায় কিছু ভুল করেছে তা দেখতে ভলগ্রিন্ডের নীচে আপনার কোডটি চালান ।


4
স্থির ভালগ্রাইন্ড অবশ্যই সাহায্য করেছিল। আমি আমার পুরনো মাতলাব কোডটি ভুল করে প্রতিলিপি করেছি এবং লুপের জন্য জেতে পুনরাবৃত্তি হয়েছিল, তারপরে এটির ভিতরে জ ++ হয়েছিল যা সর্বাধিকটিতে যে অ্যারেটি লিখছিল তা ওভাররোট করে এবং কোনওভাবে মলোককে ব্যর্থ করে দেয়। সাহায্যের জন্য ধন্যবাদ!
ক্রিস

এই ত্রুটিটি পেয়ে আমি কী চলছে তা নির্ধারণ করার জন্য ভ্যালগ্রাইন্ডটি কেবলমাত্র একটি সরঞ্জাম ছিল। এটি উল্লেখ করার জন্য ধন্যবাদ।
অ্যালেক্সওয়েলস

78

আপনাকে কেন আরও ভাল বোঝার জন্য এটি ঘটে , আমি @ আর-সামুয়েল-ক্লাটচকের উত্তরটি কিছুটা বাড়িয়ে দিতে চাই।

আপনি যখন কল করবেন তখন mallocযা যা ঘটছে তা আপনাকে আরও কিছু স্মৃতি দিয়ে খেলার চেয়ে আরও জটিল। হুডের নীচে, mallocএটি আপনাকে প্রদত্ত মেমোরি সম্পর্কে কিছু বাড়ির রক্ষণাবেক্ষণের তথ্য রাখে (সর্বাপেক্ষা গুরুত্বপূর্ণ, এর আকার), যাতে আপনি যখন কল করবেন তখন freeএটি মেমরিটি কতটা মুক্ত করতে হবে তা জানে। এই তথ্যটি সাধারণত মেমরির অবস্থানটি আপনাকে ফেরত দেওয়ার আগে ঠিক রাখা হয় malloc। আরও বিস্তৃত তথ্য ইন্টারনেটে পাওয়া যাবে but তবে (খুব) প্রাথমিক ধারণাটি এরকম কিছু:

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

সুতরাং, আপনার ত্রুটির কারণ কি?

ঠিক আছে, কল্পনা করুন যে আপনার কোডটি ভুলভাবে আপনার বরাদ্দ করা মেমরির পরিমাণটি লিখেছিল (হয় কারণ আপনি নিজের সমস্যা হিসাবে আপনার প্রয়োজনের চেয়ে কম বরাদ্দ দিয়েছেন বা আপনি কোথাও কোথাও ভুল সীমানা শর্ত ব্যবহার করছেন)। আপনার কোড এত ডাটা লিখেছেন বলুন p2এটা মুছে যাওয়ার কি হয় শুরু হয় যে p3এর sizeক্ষেত্র। আপনি এখন যখন পরবর্তী কল করবেন তখন mallocএটি ফিরে আসা শেষ মেমরিটির অবস্থানটি দেখবে, এর আকারের ক্ষেত্রটি দেখবে, সেখানে চলে যাবে p3 + sizeএবং সেখান থেকে মেমরি বরাদ্দ শুরু করবে। যেহেতু আপনার কোডটি ওভাররাইট হয়েছে size, তবে এই মেমরির অবস্থানটি আগের বরাদ্দ মেমরির পরে আর নেই।

বলা বাহুল্য, এটি বিধ্বস্ত হতে পারে! এর বাস্তবায়নকারীরা mallocবেশ কয়েকটি "দৃ as়তা" বা চেক রেখেছেন, তারা যদি ঘটতে চলেছে তবে এটি (এবং অন্যান্য সমস্যাগুলি) ধরার জন্য একগুচ্ছ স্যানিটি চেক করার চেষ্টা করে। আপনার বিশেষ ক্ষেত্রে, এই দাবিগুলি লঙ্ঘন করা হয়েছে, এবং এইভাবেmalloc বাতিল হয়ে যায়, আপনাকে বলে যে আপনার কোডটি এমন কিছু করতে যাচ্ছিল যা এটি করা উচিত নয়।

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


17

ভালগ্রাইন্ড ব্যবহারের জন্য আমার বিকল্প সমাধান:

আমি খুব খুশি কারণ আমি কেবলমাত্র আমার বন্ধুকে একটি প্রোগ্রাম ডিবাগ করতে সহায়তা করেছি। malloc()জিডিবি-র একই ত্রুটি বার্তায় তাঁর প্রোগ্রামটিতে এই সঠিক সমস্যাটি ( গর্ভপাত বন্ধ করে দেওয়া) হয়েছিল।

আমি ঠিকানা স্যানিটাইজার দিয়ে তার প্রোগ্রামটি সংকলন করেছি

এবং তারপর দৌড়ে gdb newSIGABRTপরবর্তী সময়ে প্রোগ্রামটি যখন শেষ হয়ে যায়, তখন malloc()পুরো প্রচুর দরকারী তথ্য মুদ্রিত হয়:

আসুন আউটপুট, বিশেষত স্ট্যাক ট্রেসটি একবার দেখুন:

প্রথম অংশটি বলে যে এখানে একটি অবৈধ রাইটিং অপারেশন রয়েছে new.c:59। এই লাইন পড়ে

দ্বিতীয় অংশটি বলেছে যে খারাপ লেখাটি যে স্মৃতিতে হয়েছিল তা তৈরি হয়েছিল new.c:55। এই লাইন পড়ে

এটাই. আমার বন্ধুটিকে কয়েক ঘন্টা বিভ্রান্ত করে এমন বাগটি সনাক্ত করতে আমার কাছে কেবল আধা মিনিটেরও কম সময় লেগেছে। তিনি ব্যর্থতা সনাক্ত করতে সক্ষম হন, তবে এটি পরবর্তী malloc()কোড যা এই ব্যর্থতাটি আগের কোডটিতে এই ত্রুটিটি চিহ্নিত না করে ব্যর্থ হয়েছিল failed

যোগফল: -fsanitize=addressজিসিসি বা কলঙ্কের চেষ্টা করুন । মেমরির সমস্যাগুলি ডিবাগ করার সময় এটি খুব সহায়ক হতে পারে।


4
আপনি সবেমাত্র আমার জীবন বাঁচিয়েছেন।
নেট সিমার

2

আপনি সম্ভবত বরাদ্দ মেম কোথাও কোথাও ছাড়িয়ে যাচ্ছেন। তারপরে অন্তর্নিহিত sw এটি পর্যন্ত গ্রহণ করবে না যতক্ষণ না আপনি ম্যালোককে কল করেন

মলোক ধরা পড়ে এমন এক গার্ড মান থাকতে পারে b

সম্পাদনা ... সীমানা যাচাইয়ের সহায়তার জন্য এটি যুক্ত করা হয়েছে

http://www.lrde.epita.fr/~akim/ccmp/doc/bounds-checking.html


2

আপনার অনুরূপ নিম্নলিখিত বার্তাটি পেয়েছি:

    প্রোগ্রাম: malloc.c: 2372: সিসমলোক: দৃ`়তা `(পুরাতন_টপ == (((এমবিিনપ્টার)) (((চর *)) এবং ((এভ))> বিনগুলি [((1) - 1) * 2])) - __ বিল্টিন_ অফসেটফ (স্ট্রাক্ট malloc_chunk, fd))) && ওল্ড_সাইজ == 0) || ((স্বাক্ষরযুক্ত দীর্ঘ) (ওল্ড সাইজ)> = (স্বাক্ষরযুক্ত দীর্ঘ) (((__ বিল্টিন_ অফসেটফ (স্ট্রাক্ট ম্যালোক_চঙ্ক, এফডি_নেক্সটসাইজ))) + ((2 * (আকারের (আকার_টি)))) - 1)) & ~ ((2 * (আকারে (আকার_টি))) - ১))) && ((ওল্ড_টপ))> আকার এবং 0x1) && ((স্বাক্ষরযুক্ত দীর্ঘ) ওল্ড_ইন্ড এবং পেজমাস্ক) == 0) 'ব্যর্থ হয়েছে।

Malloc ব্যবহার করার আগে কিছু পদ্ধতি কল করার আগে ভুল করে ফেলেছে। স্বাক্ষরযুক্ত চর অ্যারেতে ক্ষেত্র যোগ করার ক্ষেত্রে মাপের () - অপারেটরের পরে ফ্যাক্টরটি আপডেট করার সময়, ভুলভাবে একটি '+' দিয়ে গুণফল '*' ওভাররোট করুন।

আমার ক্ষেত্রে ত্রুটির জন্য দায়ী কোডটি এখানে:

    UCHAR * b = (UCHAR *) malloc (আকারের (UCHAR) +5);
    b [INTBITS] = (কিছু গণনা);
    b [BUFSPC] = (কিছু গণনা);
    b [BUFOVR] = (কিছু গণনা);
    b [BUFMEM] = (কিছু গণনা);
    b [MATCHBITS] = (কিছু গণনা);

পরে অন্য একটি পদ্ধতিতে, আমি আবার malloc ব্যবহার করেছি এবং এটি উপরে প্রদর্শিত ত্রুটি বার্তাটি তৈরি করেছে। কলটি ছিল (যথেষ্ট সহজ):

    UCHAR * b = (UCHAR *) malloc (আকারের (UCHAR) * 50);

'+' ব্যবহার করে ভাবুন - 1 ম কলটিতে সাইন, যা পরে অ্যারের তাত্ক্ষণিক সূচনার সাথে মিশে ভুল-ক্যালকুলাসের দিকে পরিচালিত করে (মেমরির উপরে ওভাররাইটিং যা অ্যারেতে বরাদ্দ করা হয়নি), মলকের স্মৃতি মানচিত্রে কিছুটা বিভ্রান্তি এনেছে। সুতরাং দ্বিতীয় কলটি ভুল হয়ে গেছে went


0

আমরা এই ত্রুটিটি পেয়েছি কারণ আমরা আকারের (গুণাগুণ) দ্বারা গুণ করতে ভুলে গেছি। ম্যালোক (..) এর আর্গুমেন্টটি কয়েকটি বাইট, মেশিন শব্দের সংখ্যা বা যাই হোক না কেন not


0

আমি একই সমস্যা পেয়েছি, নতুন চর * স্ট্রিং ডেটা যুক্ত করার জন্য আমি আবার একটি লুপে n এর ওপরে malloc ব্যবহার করেছি। আমি একই সমস্যার মুখোমুখি হয়েছি, তবে বরাদ্দ মেমরির void free()সমস্যা প্রকাশের পরে বাছাই করা হয়েছিল


-2

আমি লিনাক্সের উপর ভিসুয়াল সি থেকে জিসিসি-তে একটি অ্যাপ্লিকেশন পোর্ট করছি এবং আমারও একই সমস্যা ছিল

malloc.c: 3096: sYSMALLOc: ইউবিএনটিইউ 11-তে জিসিসি ব্যবহারের জন্য জোর দেওয়া।

আমি একই কোডটিকে স্যু বিতরণে স্থানান্তরিত করেছি (অন্য কম্পিউটারে) এবং আমার কোনও সমস্যা নেই any

আমি সন্দেহ করি যে সমস্যাগুলি আমাদের প্রোগ্রামগুলিতে নয় বরং নিজস্ব লাইবসিটিতে রয়েছে।

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