ঠিকানা স্যানিটাইজার ব্যবহার করে মেমরি দুর্নীতি ডিবাগ করা

এই নথিটি আপনাকে দেখায় যে কীভাবে AGDE ব্যবহার করার সময় বিশেষ ডিবাগিং সরঞ্জামগুলি সক্ষম করতে হয়৷ এই সরঞ্জামগুলি মেমরি দুর্নীতি এবং ওভাররাইট ত্রুটিগুলিকে কঠিনভাবে নির্ণয় করতে সহায়তা করতে পারে।

এইচডব্লিউএড্রেস স্যানিটাইজার এবং অ্যাড্রেস স্যানিটাইজার

HWAddress Sanitizer (HWASan) এবং Address Sanitizer (ASan) হল মেমরি দুর্নীতি ডিবাগিং টুল যা মেমরি দুর্নীতি ডিবাগ করতে সাহায্য করে এবং ত্রুটিগুলি ওভাররাইট করতে সাহায্য করে, যেমন নিম্নলিখিত:

  • স্ট্যাক বাফার ওভারফ্লো এবং underflows
  • গাদা বাফার ওভারফ্লো এবং underflows
  • স্ট্যাক ব্যবহার এর সুযোগের বাইরে
  • ডাবল ফ্রি এবং ওয়াইল্ড ফ্রি ত্রুটি
  • ফিরে আসার পরে স্ট্যাক ব্যবহার (শুধু HWASan)

আপনি যখন কোনো সমস্যা ডিবাগ করছেন বা স্বয়ংক্রিয় পরীক্ষার অংশ হিসেবে শুধুমাত্র তখনই HWASan বা ASan সক্রিয় করার পরামর্শ দিই। এই সরঞ্জামগুলি কার্যকরী হলেও, তাদের ব্যবহারে একটি জরিমানা গুনতে হয়৷

রানটাইম আচরণ

সক্রিয় করা হলে, HWASan এবং ASan উভয়ই স্বয়ংক্রিয়ভাবে আপনার অ্যাপে মেমরি দুর্নীতির জন্য পরীক্ষা করে।

যদি একটি মেমরি ত্রুটি সনাক্ত করা হয়, অ্যাপটি একটি SIGBART (সংকেত বাতিল) ত্রুটির সাথে ক্র্যাশ করে এবং logcat এ একটি বিশদ বার্তা প্রিন্ট করে৷ বার্তাটির একটি অনুলিপি /data/tombstones অধীনে একটি ফাইলেও লেখা হয়।

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

ERROR: HWAddressSanitizer: tag-mismatch on address 0x0042a0826510 at pc 0x007b24d90a0c
WRITE of size 1 at 0x0042a0826510 tags: 32/3d (ptr/mem) in thread T0
    #0 0x7b24d90a08  (/data/app/com.example.hellohwasan-eRpO2UhYylZaW0P_E0z7vA==/lib/arm64/libnative-lib.so+0x2a08)
    #1 0x7b8f1e4ccc  (/apex/com.android.art/lib64/libart.so+0x198ccc)
    #2 0x7b8f1db364  (/apex/com.android.art/lib64/libart.so+0x18f364)
    #3 0x7b8f2ad8d4  (/apex/com.android.art/lib64/libart.so+0x2618d4)

0x0042a0826510 is located 0 bytes to the right of 16-byte region [0x0042a0826500,0x0042a0826510)
allocated here:
    #0 0x7b92a322bc  (/apex/com.android.runtime/lib64/bionic/libclang_rt.hwasan-aarch64-android.so+0x212bc)
    #1 0x7b24d909e0  (/data/app/com.example.hellohwasan-eRpO2UhYylZaW0P_E0z7vA==/lib/arm64/libnative-lib.so+0x29e0)
    #2 0x7b8f1e4ccc  (/apex/com.android.art/lib64/libart.so+0x198ccc)

পূর্বশর্ত

HWASan প্রয়োজনীয়তা

HWASan ব্যবহার করতে:

  • আপনাকে অবশ্যই AGDE 24.1.99 বা উচ্চতর ব্যবহার করতে হবে।
  • অ্যাপটি অবশ্যই NDK 26 বা তার বেশি ব্যবহার করে তৈরি করতে হবে।
  • অ্যাপটি অবশ্যই টার্গেট SDK 34 বা তার বেশি দিয়ে তৈরি করতে হবে।
  • লক্ষ্যটি অবশ্যই Android 14 (API স্তর 34) বা উচ্চতর চলমান একটি arm64-v8a ডিভাইস হতে হবে।

আপনার প্রকল্পে শেয়ার করা C++ স্ট্যান্ডার্ড লাইব্রেরি ব্যবহার করুন

একটি পরিচিত সমস্যার কারণে, libc++_static ব্যবহার করার সময় ASan C++ ব্যতিক্রম পরিচালনার সাথে বেমানান। libc++_shared ব্যবহার করার সময় এই সমস্যাটি দেখা যায় না।

HWASan-এর নিজস্ব অপারেটর new এবং delete এর বাস্তবায়ন রয়েছে, যা স্ট্যান্ডার্ড লাইব্রেরি প্রকল্পের সাথে স্ট্যাটাসলি লিঙ্ক করা থাকলে ব্যবহার করা যাবে না।

এই সেটিং পরিবর্তন করতে, এই নথির C++ স্ট্যান্ডার্ড লাইব্রেরির লিঙ্কিং বিভাগটি দেখুন।

ফ্রেম পয়েন্টার জেনারেশন সক্ষম করুন

HWASan এবং ASan মেমরি বরাদ্দ এবং ডিললোকেশন ইভেন্টগুলির জন্য স্ট্যাক ট্রেস তথ্য তৈরি করতে একটি দ্রুত ফ্রেম পয়েন্টার-ভিত্তিক আনউইন্ডার ব্যবহার করে। এর মানে হল এই বৈশিষ্ট্যগুলি ব্যবহার করার জন্য আপনাকে অবশ্যই আপনার C++ কম্পাইলার সেটিংসে ফ্রেম পয়েন্টার জেনারেশন সক্ষম করতে হবে। অর্থাৎ, আপনাকে ফ্রেম পয়েন্টার অপটিমাইজেশন অক্ষম করতে হবে।

এই সেটিং পরিবর্তন করতে, এই নথির ফ্রেম পয়েন্টার জেনারেশন সক্ষম করা বিভাগটি দেখুন।

HWASan বা ASan ব্যবহার করার জন্য আপনার ভিজ্যুয়াল স্টুডিও প্রকল্প কনফিগার করা হচ্ছে

HWASan বা ASan সক্রিয় করা হচ্ছে

HWASan বা ASan সক্ষম করতে, আপনার প্রকল্পের জন্য সম্পত্তি পৃষ্ঠাগুলিতে কনফিগারেশন বৈশিষ্ট্য > সাধারণ- এ যান।

বর্তমানের জন্য ভিজ্যুয়াল স্টুডিও সলিউশন এক্সপ্লোরার বৈশিষ্ট্য মেনু প্রকল্প

চিত্র 1 : ভিজ্যুয়াল স্টুডিও সলিউশন এক্সপ্লোরার উইন্ডোতে প্রকল্পের বৈশিষ্ট্য বিকল্প।

প্রজেক্ট প্রপার্টি পেজ ডায়ালগ সাধারণ বৈশিষ্ট্য সহ দেখানো হয়েছে, এবং ঠিকানা স্যানিটাইজার সেটিংস হাইলাইট করা হয়েছে।

চিত্র 2 : সাধারণ প্রকল্পের বৈশিষ্ট্যে ঠিকানা স্যানিটাইজার (আসান) সেটিং।

আপনার প্রকল্পের জন্য HWASan সক্ষম করতে, ঠিকানা স্যানিটাইজার (ASan) সেটিং পরিবর্তন করে হার্ডওয়্যার ASan সক্ষম (fsanitize=hwaddress) করুন

আপনার প্রকল্পের জন্য ASan সক্ষম করতে, ঠিকানা স্যানিটাইজার (ASan) সেটিংস পরিবর্তন করে ASan সক্ষম (fsanitize=address) করুন

ফ্রেম পয়েন্টার জেনারেশন সক্ষম করা হচ্ছে

ফ্রেম পয়েন্টার জেনারেশন ওমিট ফ্রেম পয়েন্টার C/C++ কম্পাইলার সেটিং দ্বারা নিয়ন্ত্রিত হয় এবং কনফিগারেশন প্রপার্টিজ > C/C++ > অপ্টিমাইজেশনের অধীনে আপনার প্রোজেক্ট প্রপার্টি পেজে পাওয়া যাবে।

C/C++ অপ্টিমাইজেশান বৈশিষ্ট্য সহ প্রজেক্ট প্রপার্টি পেজ ডায়ালগ দেখানো হয়েছে, এবং ফ্রেম পয়েন্টার সেটিংস বাদ দিন হাইলাইট

চিত্র 3 : কোথায় পাবেন ওমিট ফ্রেম পয়েন্টার সেটিং।

HWASan বা ASan ব্যবহার করার সময়, Omit Frame Pointer সেটিং No (-fno-omit-frame-pointer) সেট করুন।

শেয়ার্ড লাইব্রেরি মোডে C++ স্ট্যান্ডার্ড লাইব্রেরি লিঙ্ক করা

C++ স্ট্যান্ডার্ড লাইব্রেরির জন্য লিঙ্কার মোড সেটিং আপনার প্রোজেক্টের প্রোপার্টি পৃষ্ঠাগুলিতে কনফিগারেশন প্রোপার্টিজ > জেনারেলের অধীনে, প্রোজেক্ট ডিফল্ট বিভাগে পাওয়া যাবে।

প্রজেক্ট প্রোপার্টি পেজ ডায়ালগ সাধারণ ক্যাটাগরির সাথে নির্বাচিত, এবং STL সেটিং ব্যবহার হাইলাইট

চিত্র 4 : C++ স্ট্যান্ডার্ড লাইব্রেরির জন্য লিঙ্কার মোড সেটিং কোথায় পাবেন।

HWASan বা ASan ব্যবহার করার সময়, C++ স্ট্যান্ডার্ড লাইব্রেরি (.so) ব্যবহার করতে STL-এর ব্যবহার সেট করুন। এই মানটি আপনার প্রকল্পে C++ স্ট্যান্ডার্ড লাইব্রেরিকে একটি শেয়ার্ড লাইব্রেরি হিসেবে লিঙ্ক করে, যা HWASan এবং ASan সঠিকভাবে কাজ করার জন্য প্রয়োজনীয়।

অ্যাড্রেস স্যানিটাইজার ব্যবহারের জন্য একটি বিল্ড কনফিগারেশন তৈরি করা

আপনি যদি HWASan বা ASan ক্ষণস্থায়ীভাবে ব্যবহার করতে পছন্দ করেন তবে আপনি শুধুমাত্র তাদের ব্যবহারের জন্য একটি নতুন বিল্ড কনফিগারেশন তৈরি করতে চান না। আপনার প্রকল্পটি ছোট হলে, আপনি বৈশিষ্ট্যটি অন্বেষণ করছেন, বা পরীক্ষার সময় আপনি যে সমস্যাটি আবিষ্কার করছেন তার প্রতিক্রিয়া হিসাবে এটি হতে পারে।

যাইহোক, যদি আপনি এটিকে উপযোগী মনে করেন এবং এটি নিয়মিত ব্যবহার করার পরিকল্পনা করেন, তাহলে আপনি টিপট নমুনায় প্রদর্শিত হিসাবে HWASan বা ASan-এর জন্য একটি নতুন বিল্ড কনফিগারেশন তৈরি করার কথা বিবেচনা করতে পারেন। আপনি এটি করতে পারেন যদি, উদাহরণস্বরূপ, আপনি আপনার ইউনিট পরীক্ষার অংশ হিসাবে নিয়মিত অ্যাড্রেস স্যানিটাইজার চালান, বা আপনার গেমের রাতারাতি ধোঁয়া-পরীক্ষার সময়।

একটি পৃথক বিল্ড কনফিগারেশন তৈরি করা বিশেষভাবে উপযোগী হতে পারে যদি আপনার কাছে একটি বড় প্রকল্প থাকে যা বিপুল সংখ্যক বিভিন্ন তৃতীয় পক্ষের লাইব্রেরি ব্যবহার করে যেখানে আপনি সাধারণত C++ স্ট্যান্ডার্ড লাইব্রেরির সাথে স্ট্যাটাসলি লিঙ্ক করেন। ডেডিকেটেড বিল্ড কনফিগারেশন আপনার প্রোজেক্ট সেটিংস সব সময়ে সঠিক থাকে তা নিশ্চিত করতে সাহায্য করতে পারে।

একটি বিল্ড কনফিগারেশন তৈরি করতে, আপনার প্রকল্পের সম্পত্তি পৃষ্ঠাগুলি থেকে, কনফিগারেশন ম্যানেজার… বোতামে ক্লিক করুন, এবং তারপর সক্রিয় সমাধান কনফিগারেশন ড্রপ-ডাউন খুলুন। তারপর নির্বাচন , এবং একটি উপযুক্ত নাম দিয়ে একটি নতুন বিল্ড কনফিগারেশন তৈরি করুন (উদাহরণস্বরূপ, HWASan enabled )।

কাস্টম মেমরি বরাদ্দকারীর সাথে HWASan ব্যবহার করা

HWASan স্বয়ংক্রিয়ভাবে malloc (বা new ) এর মাধ্যমে বরাদ্দ করা মেমরিকে বাধা দেয় যাতে এটি পয়েন্টারগুলিতে ট্যাগগুলি ইনজেকশন করতে পারে এবং ট্যাগের অমিলগুলি পরীক্ষা করতে পারে।

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

পূর্বশর্ত

আপনাকে যে HWASan পদ্ধতিগুলি কল করতে হবে তা এই হেডারে সংজ্ঞায়িত করা হয়েছে:

#include "sanitizer/hwasan_interface.h"

আপনার মেমরি বরাদ্দ পদ্ধতির উপকরণ

  1. 16-বাইট ব্লক গ্রানুলারিটি এবং প্রান্তিককরণে বস্তু বরাদ্দ করুন। উদাহরণস্বরূপ, আপনার যদি একটি পুল বরাদ্দকারী থাকে যা 24-বাইট আকারের নির্দিষ্ট-আকারের বস্তুগুলিকে পরিবেশন করে, আপনার বরাদ্দগুলি 32-বাইট পর্যন্ত রাউন্ড করুন এবং 16 বাইটে সারিবদ্ধ করুন।

  2. একটি 8-বিট ট্যাগ তৈরি করুন। আপনার ট্যাগ অবশ্যই 0-16 মান ব্যবহার করবে না, কারণ সেই মানগুলি অভ্যন্তরীণ ব্যবহারের জন্য সংরক্ষিত।

  3. সেই ট্যাগ দিয়ে মেমরি অঞ্চল ট্র্যাক করা শুরু করতে HWASan সক্ষম করুন:

    __hwasan_tag_memory((void*) address, tag, size);
    
  4. আপনার পয়েন্টারের শীর্ষ 8-বিটে ট্যাগটি ইনজেক্ট করুন:

    address = __hwasan_tag_pointer((void*) address, tag);
    

ইন্সট্রুমেন্ট আপনার মেমরি ডিলোকেশন পদ্ধতি

  1. মেমরি অঞ্চলের জন্য ট্যাগ রিসেট করুন যাতে বিদ্যমান ট্যাগ করা পয়েন্টারগুলির মাধ্যমে আরও অ্যাক্সেস ব্যর্থ হয়:

    __hwasan_tag_memory(__hwasan_tag_pointer(ptr, 0), 0, size);
    

অবজেক্টের একটি পূর্বনির্ধারিত পুলের সাথে কাজ করা

যদি আপনার মেমরি বরাদ্দকারী একটি পুলে বস্তুগুলিকে আগে থেকে বরাদ্দ করে এবং বস্তুগুলিকে প্রকৃতপক্ষে মুক্ত করার পরিবর্তে পুলে ফিরিয়ে দেয়, তাহলে আপনার ডিললোকেশন পদ্ধতিটি সরাসরি মেমরির ট্যাগ এবং একটি নতুন মান সহ পয়েন্টারকে ওভাররাইট করতে পারে:

```
__hwasan_tag_memory(__hwasan_tag_pointer(ptr, 0), tag, size);
ptr = __hwasan_tag_pointer((void*)ptr, tag);
```

আপনি যদি এই কৌশলটি ব্যবহার করেন, আপনার বরাদ্দ পদ্ধতিতে পয়েন্টার বা মেমরি ব্লক ট্যাগ করার প্রয়োজন নেই, কিন্তু আপনি যখন আপনার পুলের বস্তুগুলিকে আগে থেকে বরাদ্দ করেন তখন পয়েন্টার এবং মেমরি ব্লক ট্যাগ করুন। এই শৈলী ব্যবহার করে এমন একটি উদাহরণের জন্য PoolAllocator নমুনা দেখুন।