اشکال زدایی خرابی حافظه با استفاده از Address Sanitizer

این سند به شما نشان می دهد که چگونه هنگام استفاده از AGDE ابزارهای ویژه اشکال زدایی را فعال کنید. این ابزارها می توانند به تشخیص خرابی حافظه و خطاهای بازنویسی کمک کنند.

HWAddress Sanitizer و Address Sanitizer

HWAddress Sanitizer (HWASan) و Address Sanitizer (ASan) ابزارهای اشکال زدایی خرابی حافظه هستند که به رفع اشکال خرابی حافظه و خطاهای بازنویسی کمک می کنند، مانند موارد زیر:

  • بافر پشته سرریز و زیر سرریز می شود
  • بافر هیپ سرریز و زیر سرریز می شود
  • استفاده از پشته خارج از محدوده آن
  • خطاهای رایگان و وحشی را دو برابر کنید
  • استفاده از پشته پس از بازگشت (فقط 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، دستورالعمل‌های راه‌اندازی در اسناد HWASan را دنبال کنید تا یک ساخت HWASan از سیستم عامل Android برای دستگاه‌های Google Pixel نصب کنید.

برای سایر دستگاه‌ها، با سازنده خود تماس بگیرید تا در صورت وجود، نسخه HWASan سیستم عامل را دریافت کنید، یا از ابزار ASan فقط نرم‌افزاری استفاده کنید.

از کتابخانه استاندارد C++ مشترک در پروژه خود استفاده کنید

به دلیل یک مشکل شناخته شده، ASan هنگام استفاده از libc++_static با مدیریت استثناهای C++ ناسازگار است. این مشکل هنگام استفاده از libc++_shared دیده نمی شود.

HWASan اجرای خود را از اپراتورهای new و delete دارد، که اگر کتابخانه استاندارد به صورت ایستا به پروژه مرتبط باشد، قابل استفاده نیست.

برای تغییر این تنظیم، به بخش پیوند دادن کتابخانه استاندارد C++ این سند مراجعه کنید.

فعال کردن Frame Pointer

HWASan و ASan از یک بازکردن سریع مبتنی بر اشاره گر فریم برای تولید اطلاعات ردیابی پشته برای رویدادهای تخصیص حافظه و توزیع استفاده می کنند. این بدان معناست که برای استفاده از این ویژگی ها باید در تنظیمات کامپایلر C++ خود، تولید اشاره گر فریم را فعال کنید. یعنی باید بهینه سازی حذف نشانگر فریم را غیرفعال کنید.

برای تغییر این تنظیم، بخش Enabling Frame Pointer Generation در این سند را ببینید.

پیکربندی پروژه ویژوال استودیو برای استفاده از HWASan یا ASan

فعال کردن HWASan یا ASan

برای فعال کردن HWASan یا ASan، به Configuration Properties > General در Property Pages برای پروژه خود بروید.

منوی ویژگی های Visual Studio Solution Explorer برای پروژه فعلی.

شکل 1 : گزینه Properties پروژه در پنجره Visual Studio Solution Explorer.

گفتگوی Property Pages با مشخصات عمومی نشان داده شده و تنظیمات Address Sanitizer برجسته شده است.

شکل 2 : تنظیم Address Sanitizer (ASan) در خصوصیات کلی پروژه.

برای فعال کردن HWASan برای پروژه خود، تنظیم Address Sanitizer (ASan) را به Hardware ASan Enabled (fsanitize=hwaddress) تغییر دهید.

برای فعال کردن ASan برای پروژه خود، تنظیم Address Sanitizer (ASan) را به ASan Enabled (fsanitize=address) تغییر دهید.

فعال کردن Frame Pointer

تولید نشانگر فریم توسط تنظیمات کامپایلر Omit Frame Pointer C/C++ کنترل می‌شود و می‌توانید آن را در Property Pages پروژه خود در قسمت Configuration Properties > C/C++ > Optimization پیدا کنید.

گفتگوی Property Pages با ویژگی های C/C++ Optimization نشان داده شده و تنظیمات Omit Frame Pointer برجسته شده است.

شکل 3 : از کجا می توان تنظیمات Omit Frame Pointer را پیدا کرد.

هنگام استفاده از HWASan یا ASan، تنظیمات Omit Frame Pointer را روی No (-fno-omit-frame-pointer) قرار دهید.

پیوند دادن کتابخانه استاندارد C++ در حالت کتابخانه مشترک

تنظیمات حالت پیونددهنده برای کتابخانه استاندارد C++ را می‌توانید در صفحات ویژگی پروژه خود در قسمت خصوصیات پیکربندی > عمومی ، در بخش پیش‌فرض‌های پروژه پیدا کنید.

گفتگوی Property Pages با دسته بندی عمومی انتخاب شده و استفاده از تنظیمات STL برجسته شده است.

شکل 4 : محل پیدا کردن تنظیمات حالت پیوند دهنده برای کتابخانه استاندارد C++.

هنگام استفاده از HWASan یا ASan، Use of STL را روی Use C++ Standard Libraries (.so) تنظیم کنید. این مقدار کتابخانه استاندارد C++ را به عنوان یک کتابخانه مشترک به پروژه شما پیوند می دهد که برای عملکرد صحیح HWASan و ASan لازم است.

ایجاد یک پیکربندی Build برای استفاده از Address Sanitizer

اگر ترجیح می دهید از HWASan یا ASan به صورت موقت استفاده کنید، ممکن است نخواهید یک پیکربندی ساخت جدید را صرفاً برای استفاده آنها ایجاد کنید. اگر پروژه شما کوچک است، در حال کاوش در ویژگی یا در پاسخ به مشکلی است که در طول آزمایش متوجه شده اید، ممکن است این مورد اتفاق بیفتد.

با این حال، اگر آن را مفید می‌دانید و قصد دارید به طور منظم از آن استفاده کنید، ممکن است همانطور که در نمونه Teapot نشان داده شده است، یک پیکربندی ساخت جدید برای HWASan یا ASan ایجاد کنید. برای مثال، اگر به طور منظم Address Sanitizer را به عنوان بخشی از تست‌های واحد خود یا در طول تست‌های دود در طول شب بازی خود اجرا کنید، ممکن است این کار را انجام دهید.

ایجاد یک پیکربندی ساخت جداگانه ممکن است به ویژه مفید باشد اگر پروژه بزرگی دارید که تعداد زیادی از کتابخانه های شخص ثالث مختلف را مصرف می کند که معمولاً آنها را به طور ایستا با کتابخانه استاندارد C++ پیوند می دهید. پیکربندی های ساخت اختصاصی می تواند به اطمینان از اینکه تنظیمات پروژه شما همیشه دقیق باقی می ماند کمک کند.

برای ایجاد یک پیکربندی ساخت، از Property Pages پروژه خود، روی دکمه Configuration Manager… کلیک کنید و سپس منوی کشویی Active solution configuration را باز کنید. سپس انتخاب کنید ، و یک پیکربندی ساخت جدید با نام مناسب ایجاد کنید (به عنوان مثال، HWASan فعال شده است ).