گزارش های HWASan را درک کنید

هنگامی که ابزار HWASan یک اشکال حافظه را شناسایی می کند، فرآیند با abort() خاتمه می یابد و یک گزارش در stderr و logcat چاپ می شود. مانند تمام خرابی‌های بومی اندروید، خطاهای HWASan در زیر /data/tombstones قرار دارند.

گزارش نمونه

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

*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
Build fingerprint: 'google/flame_hwasan/flame:Tiramisu/MASTER/7956676:userdebug/dev-keys'
Revision: 'DVT1.0'
ABI: 'arm64'
Timestamp: 2019-04-24 01:13:22+0000
pid: 11154, tid: 11154, name: sensors@1.0-ser  >>> /vendor/bin/hw/android.hardware.sensors@1.0-service <<<
signal 6 (SIGABRT), code -1 (SI_QUEUE), fault addr --------
Abort message: '

[...]

[0x00433ae20040,0x00433ae20060) is a small unallocated heap chunk; size: 32 offset: 5








[ … regular crash dump follows …]

این مشابه گزارش AddressSanitizer است. برخلاف آن‌ها، تقریباً تمام اشکالات HWASan خطاهای عدم تطابق برچسب هستند، یعنی دسترسی به حافظه که در آن یک برچسب اشاره‌گر با تگ حافظه مربوطه مطابقت ندارد. این می تواند یکی از موارد زیر باشد:

  • دسترسی خارج از محدوده در پشته یا پشته
  • خطای استفاده پس از رایگان در پشته
  • خطای استفاده پس از بازگشت در پشته

بخش ها

در اینجا توضیحی در مورد هر یک از بخش های گزارش HWASan آورده شده است.

خطای دسترسی

حاوی اطلاعاتی در مورد دسترسی بد حافظه است، از جمله:

  • نوع دسترسی ( READ در مقابل WRITE )
  • اندازه دسترسی (چند بایت سعی شد به آن دسترسی پیدا کرد)
  • شماره موضوع دسترسی
  • نشانگر و برچسب های حافظه (برای اشکال زدایی پیشرفته)

دسترسی به ردیابی پشته

پشته ردی از دسترسی به حافظه بد. برای نمادسازی به نمادسازی مراجعه کنید.

علت

علت بالقوه دسترسی بد اگر چند نامزد وجود داشته باشد، آنها به ترتیب احتمال نزولی فهرست می شوند. قبل از اطلاعات دقیق در مورد علت احتمالی. HWASan می تواند علل زیر را تشخیص دهد:

  • بعد از رایگان استفاده کنید
  • عدم تطابق برچسب پشته، که می تواند استفاده پشته پس از بازگشت، استفاده پشته پس از محدوده، یا خارج از محدوده باشد
  • سرریز بافر هیپ
  • سرریز جهانی

اطلاعات حافظه

آنچه را که HWASan در مورد حافظه مورد دسترسی می داند، توصیف می کند و می تواند بر اساس نوع اشکال متفاوت باشد:

نوع اشکال علت فرمت گزارش
عدم تطابق برچسب بعد از رایگان استفاده کنید از این فرمت گزارش استفاده کنید:
<address> is located N bytes inside of M-byte region [<start>, <end>)
freed by thread T0 here:
سرریز بافر هیپ توجه داشته باشید که این نیز می تواند یک جریان زیرین باشد.
<address> is located N bytes to the right of M-byte region [<start>, <end>)
allocated here:
عدم تطابق برچسب پشته گزارش‌های پشته‌ای تفاوتی بین اشکالات سرریز یا کم‌روی و استفاده پس از بازگشت قائل نمی‌شوند. علاوه بر این، برای یافتن تخصیص پشته که منبع خطا است، یک مرحله نمادسازی آفلاین مورد نیاز است. به درک گزارش های پشته مراجعه کنید.
رایگان نامعتبر است بعد از رایگان استفاده کنید دو باگ رایگان. اگر این اتفاق هنگام خاموش شدن فرآیند رخ دهد، این می تواند نشان دهنده نقض ODR باشد.
<address> is located N bytes inside of M-byte region [<start>, <end>)
freed by thread T0 here:
نمی توان آدرس را توصیف کرد یا یک wild free (بدون حافظه ای که قبلا تخصیص داده نشده بود)، یا یک مضاعف رایگان پس از خروج حافظه اختصاص داده شده از بافر رایگان HWASan.
0x... حافظه سایه HWAsan است رایگان وحشی، زیرا برنامه در تلاش بود حافظه داخلی HWASan را آزاد کند.

ردیابی پشته تخصیص

پشته ردی از جایی که حافظه اختصاص داده شده است. ارائه فقط برای اشکالات پس از استفاده رایگان یا نامعتبر. برای نمادسازی به نمادسازی مراجعه کنید.

ردیابی پشته تخصیص

ردیابی پشته ای از جایی که حافظه تخصیص داده شده است. برای نمادسازی به نمادسازی مراجعه کنید.

اطلاعات رفع اشکال پیشرفته

گزارش HWASan همچنین دارای برخی از اطلاعات رفع اشکال پیشرفته است، از جمله (به ترتیب):

  1. لیست رشته های در حال انجام
  2. لیست رشته های در حال انجام
  3. مقدار تگ های حافظه در نزدیکی حافظه خطا
  4. تخلیه رجیسترها در نقطه دسترسی به حافظه

تخلیه تگ حافظه

می توانید از حافظه تگ برای جستجوی تخصیص حافظه نزدیک با همان تگ نشانگر استفاده کنید. این تگ ها می توانند به دسترسی خارج از محدوده با یک افست بزرگ اشاره کنند. یک تگ مربوط به 16 بایت حافظه است. تگ اشاره گر 8 بیت بالای آدرس است. تخلیه حافظه تگ می تواند نکاتی را ارائه دهد، به عنوان مثال، موارد زیر یک سرریز بافر در سمت راست است:

tags: ad/5c (ptr/mem)
[...]
Memory tags around the buggy address (one tag corresponds to 16 bytes):
  0x006f33ae1ff0: 0e  0e  0e  57  20  20  20  20  20  2e  5e  5e  5e  5e  5e  b5
=>0x006f33ae2000: f6  f6  f6  f6  f6  4c  ad  ad  ad  ad  ad  ad [5c] 5c  5c  5c
  0x006f33ae2010: 5c  04  2e  2e  2e  2e  2e  2f  66  66  66  66  66  80  6a  6a
Tags for short granules around the buggy address (one tag corresponds to 16 bytes):
  0x006f33ae1ff0: ab  52  eb  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..
=>0x006f33ae2000: ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  .. [..] ..  ..  ..
  0x006f33ae2010: ..  5c  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..

به اجرای 6 × 16 = 96 بایت تگ های ad در سمت چپ توجه کنید که با تگ اشاره گر مطابقت دارند.

اگر اندازه یک تخصیص مضرب 16 نباشد، بقیه اندازه به عنوان تگ حافظه و تگ به عنوان یک تگ گرانول کوتاه ذخیره می شود. در مثال قبلی، درست بعد از ad تگ تخصیص پررنگ، یک تخصیص 5 × 16 + 4 = 84 بایت از برچسب 5c داریم.

یک تگ حافظه صفر (به عنوان مثال، tags: ad/ 00 (ptr/mem) ) نشان‌دهنده یک باگ استفاده از پشته پس از بازگشت است.

ثبت دامپ

تخلیه ثبت در گزارش های HWASan مطابق با دستورالعملی است که دسترسی به حافظه نامعتبر را انجام می دهد. این تخلیه توسط یک رجیستری دیگر از کنترل کننده سیگنال معمولی اندروید دنبال می شود. Dump دوم را نادیده بگیرید ، همانطور که زمانی که HWASan abort() را فراخوانی کرد، گرفته شد و به باگ مربوط نیست.

نمادسازی

برای دریافت نام توابع و شماره خطوط در ردیابی پشته (و دریافت نام متغیرها برای اشکالات استفاده پس از محدوده)، یک مرحله نمادسازی آفلاین مورد نیاز است.

راه اندازی برای اولین بار: llvm-symbolizer را نصب کنید

برای نماد، سیستم شما باید llvm-symbolizer نصب شده و از $PATH قابل دسترسی باشد. در دبیان، می توانید آن را با استفاده از sudo apt install llvm نصب کنید.

فایل های نماد را دریافت کنید

برای نمادسازی، ما نیاز به باینری های بدون علامت حاوی نمادها داریم. مکان آنها به نوع ساخت بستگی دارد:

  • برای ساخت‌های محلی ، فایل‌های نماد در out/target/product/<product>/symbols/ هستند.
  • برای ساخت‌های AOSP (به‌عنوان مثال، فلش‌شده از Android Flash Tool )، بیلدها روی Android CI هستند. در Artifacts برای ساخت، یک ${PRODUCT}-symbols-${BUILDID}.zip وجود دارد.
  • برای ساخت‌های داخلی سازمانتان، اسناد سازمان خود را برای کمک به دریافت فایل‌های نماد بررسی کنید.

نمادسازی کنید

hwasan_symbolize --symbols <DECOMPRESSED_DIR>/out/target/product/*/symbols < crash

گزارش های پشته را درک کنید

برای اشکالاتی که با متغیرهای پشته رخ می دهد، گزارش HWASan حاوی جزئیاتی مانند زیر است:

Cause: stack tag-mismatch
Address 0x007d4d251e80 is located in stack of thread T64
Thread: T64 0x0074000b2000 stack: [0x007d4d14c000,0x007d4d255cb0) sz: 1088688 tls: [0x007d4d255fc0,0x007d4d259000)
Previously allocated frames:
  record_addr:0x7df7300c98 record:0x51ef007df3f70fb0  (/apex/com.android.art/lib64/libart.so+0x570fb0)
  record_addr:0x7df7300c90 record:0x5200007df3cdab74  (/apex/com.android.art/lib64/libart.so+0x2dab74)
  [...]

برای کمک به درک اشکالات پشته، HWASan فریم های پشته گذشته را ردیابی می کند. HWASan اینها را در گزارش اشکال به محتوای قابل فهم برای انسان تبدیل نمی کند و به یک مرحله نمادسازی اضافی نیاز دارد.

نقض ODR

برخی از اشکالات بدون استفاده گزارش شده توسط HWASan می تواند نشان دهنده نقض یک قانون یک تعریف (ODR) باشد. نقض ODR زمانی اتفاق می‌افتد که یک متغیر چندین بار در یک برنامه تعریف شود. این همچنین به این معنی است که متغیر چندین بار تخریب می شود که می تواند منجر به خطای استفاده پس از آزاد شدن شود.

پس از نمادسازی، نقض ODR یک خطای استفاده پس از آزاد شدن را با __cxa_finalize نشان می‌دهد، هم در پشته دسترسی نامعتبر و هم در پشته آزاد شده اینجا . پشته ای که قبلاً در اینجا تخصیص داده شده بود حاوی __dl__ZN6soinfo17call_constructorsEv است و باید به مکانی در برنامه شما اشاره کند که متغیر بالاتر روی پشته را تعریف می کند.

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

عیب یابی

در این بخش برخی از خطاها و نحوه رفع آنها توضیح داده شده است.

HWAddressSanitizer نمی تواند آدرس را با جزئیات بیشتری توضیح دهد

گاهی اوقات فضای HWASan برای اطلاعات مربوط به تخصیص حافظه گذشته تمام می شود. در این مورد، گزارش فقط شامل یک ردیابی پشته برای دسترسی فوری به حافظه است، به دنبال آن یک یادداشت:

HWAddressSanitizer can not describe address in more detail.

در برخی موارد، می توانید این مشکل را با اجرای چندین بار تست حل کنید. گزینه دیگر افزایش اندازه تاریخچه HWASan است. می توانید این کار را به صورت سراسری در build/soong/cc/sanitize.go (به دنبال hwasanGlobalOptions بگردید) یا در محیط پردازش خود (برای مشاهده تنظیمات فعلی adb shell echo $HWASAN_OPTIONS امتحان کنید) انجام دهید.

این خطا همچنین می تواند در صورتی رخ دهد که حافظه مورد نظر نقشه برداری نشده باشد یا توسط یک تخصیص دهنده غیر آگاه از HWASan تخصیص داده شود. در این مورد، تگ mem فهرست شده در هدر خرابی به طور کلی 00 است. اگر به سنگ قبر کامل دسترسی دارید، ممکن است مفید باشد که با اطلاعات مربوط به نقشه های حافظه مشورت کنید تا دریابید که آدرس مربوط به کدام نقشه (در صورت وجود) است.

اشکال تو در تو در همان تاپیک

این به این معنی است که هنگام ایجاد گزارش تصادف HWASan یک اشکال وجود دارد. این معمولاً به دلیل وجود اشکال در زمان اجرا HWASan است. یک اشکال را بایگانی کنید و در صورت امکان دستورالعمل هایی را برای نحوه بازتولید مشکل ارائه دهید.