هنگامی که ابزار HWASan یک اشکال حافظه را شناسایی می کند، فرآیند با abort()
خاتمه می یابد و یک گزارش در stderr و logcat چاپ می شود. مانند تمام خرابی های بومی اندروید، خطاهای HWASan را می توان در زیر /data/tombstones
پیدا کرد.
در مقایسه با تصادفهای بومی معمولی، HWASan اطلاعات بیشتری را در قسمت «پیام لغو» در نزدیکی بالای سنگ قبر حمل میکند. نمونه خرابی مبتنی بر پشته را در زیر ببینید (برای اشکالات پشته، به یادداشت زیر برای بخشهای خاص پشته مراجعه کنید).
گزارش نمونه
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 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: '==9569==ERROR: HWAddressSanitizer: tag-mismatch on address 0x00433ae20045 at pc 0x00623ae2a9cc READ of size 1 at 0x00433ae20045 tags: 5b/83 (ptr/mem) in thread T0 #0 0x7240450c68 (/system/lib64/vndk-sp-R/libcutils.so+0x8c68) #1 0x723dffd490 (/vendor/lib64/sensors.ssc.so+0x34490) #2 0x723e0126e0 (/vendor/lib64/sensors.ssc.so+0x496e0) [...] [0x00433ae20040,0x00433ae20060) is a small unallocated heap chunk; size: 32 offset: 5 Cause: use-after-free 0x00433ae20045 is located 5 bytes inside of 10-byte region [0x00433ae20040,0x00433ae2004a) freed by thread T0 here: #0 0x72404d1b18 (/system/lib64/libclang_rt.hwasan-aarch64-android.so+0x10b18) #1 0x723af23040 (/vendor/lib64/libgralloccore.so+0x5040) #2 0x723af23fa4 (/vendor/lib64/libgralloccore.so+0x5fa4) [...] previously allocated here: #0 0x72404ce554 (/system/lib64/libclang_rt.hwasan-aarch64-android.so+0xd554) #1 0x7240115654 (/apex/com.android.runtime/lib64/bionic/libc.so+0x43654) #2 0x7240450ac8 (/system/lib64/vndk-sp-R/libcutils.so+0x8ac8) [...] hwasan_dev_note_heap_rb_distance: 1 1023 hwasan_dev_note_num_matching_addrs: 0 hwasan_dev_note_num_matching_addrs_4b: 0 Thread: T0 0x006a00002000 stack: [0x007fc1064000,0x007fc1864000) sz: 8388608 tls: [0x00737702ffc0,0x007377033000) Memory tags around the buggy address (one tag corresponds to 16 bytes): 0x006f33ae1f80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1f90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1fa0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =>0x006f33ae2000: 08 00 08 00 [83] 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Tags for short granules around the buggy address (one tag corresponds to 16 bytes): 0x006f33ae1ff0: .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. =>0x006f33ae2000: 72 .. d0 .. [..] .. .. .. .. .. .. .. .. .. .. .. 0x006f33ae2010: .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. See https://clang.llvm.org/docs/HardwareAssistedAddressSanitizerDesign.html#short-granules for a description of short granule tags Registers where the failure occurred (pc 0x00623ae2a9cc): x0 0000007fc18623ec x1 5b0000433ae20045 x2 0000000000000013 x3 ffffffffffffffff x4 ffffffffffffffff x5 0000007fc1861da3 x6 6f7420676e696f47 x7 45522061206f6420 x8 0000000000000000 x9 0200006b00000000 x10 00000007fc18623f x11 5b0000433ae20040 x12 6f64206f7420676e x13 0a44414552206120 x14 0000000000000010 x15 ffffffffffffffff x16 000000737169ac94 x17 0000000000000007 x18 0000007377bd8000 x19 0000007fc1862498 x20 0200006b00000000 x21 0000007fc18624a8 x22 0000000000000001 x23 0000000000000000 x24 0000000000000000 x25 0000000000000000 x26 0000000000000000 x27 0000000000000000 x28 0000000000000000 x29 0000007fc1862410 x30 000000623ae2a9d0 sp 0000007fc18623d0 SUMMARY: HWAddressSanitizer: tag-mismatch (/system/lib64/vndk-sp-R/libcutils.so+0x8c68) [ … 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 همچنین دارای برخی از اطلاعات رفع اشکال پیشرفته است، از جمله (به ترتیب):
- لیست رشته های در حال انجام
- لیست رشته های در حال انجام
- مقدار تگ های حافظه در نزدیکی حافظه خطا
- تخلیه رجیسترها در نقطه دسترسی به حافظه
تخلیه تگ حافظه
تخلیه حافظه تگ می تواند برای جستجوی تخصیص حافظه در نزدیکی با همان برچسب تگ اشاره گر استفاده شود. اینها می توانند به دسترسی خارج از محدوده با افست بزرگ اشاره کنند. یک تگ مربوط به 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 نباشد، بقیه اندازه به عنوان تگ حافظه و تگ به عنوان یک تگ گرانول کوتاه ذخیره می شود. در مثال بالا، درست بعد از تگ تگ تخصیص پررنگ، تخصیص 5 × 16 + 4 = 84 بایت از برچسب 5c داریم.
یک تگ حافظه صفر (مثلاً tags: ad/ 00 (ptr/mem)
) معمولاً نشاندهنده یک باگ استفاده از پشته پس از بازگشت است.
ثبت دامپ
تخلیه ثبت در گزارش های HWASan مطابق با دستورالعمل واقعی است که دسترسی نامعتبر به حافظه را انجام داده است. به دنبال آن یک رجیستری دیگر از کنترل کننده سیگنال معمولی اندروید منتشر می شود - دومی را نادیده بگیرید ، زمانی که HWASan ()abort را فراخوانی می کند گرفته می شود و به باگ مربوط نمی شود.
نمادسازی
برای دریافت نام توابع و شماره خطوط در ردیابی پشته (و دریافت نام متغیرها برای اشکالات استفاده پس از محدوده)، یک مرحله نمادسازی آفلاین مورد نیاز است.
راه اندازی برای اولین بار: llvm-symbolizer را نصب کنید
برای نماد، سیستم شما باید llvm-symbolizer را نصب کرده و از $PATH قابل دسترسی باشد. در دبیان، می توانید آن را با استفاده از sudo apt install llvm
نصب کنید.
فایل های نماد را دریافت کنید
برای نمادسازی، ما نیاز به باینری های بدون علامت حاوی نمادها داریم. جایی که می توان آنها را یافت به نوع ساخت بستگی دارد:
برای ساختهای محلی ، فایلهای نماد را میتوان در out/target/product/<product>/symbols/
پیدا کرد.
برای ساختهای AOSP (مثلاً فلششده از Flashstation )، بیلدها را میتوانید در 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
نشان میدهد، هم در پشته دسترسی نامعتبر و هم در پشته «در اینجا آزاد شده». پشته "previously allocated here" حاوی __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 است، لطفاً یک اشکال را ثبت کنید و در صورت امکان دستورالعملهایی در مورد نحوه بازتولید آن ارائه دهید.