عندما ترصد أداة HWASan خطأً في الذاكرة، يتم إنهاء العملية باستخدام "abort()
".
تتم طباعة تقرير على stderr وLogcat. مثل جميع الأعطال الأصلية في Android، يمكن إصلاح أخطاء 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 تشخيص الأسباب التالية:
- الاستخدام بعد المجاني
- عدم تطابق علامة stack: يمكن أن يكون stack-after-return / الاستخدام بعد النطاق خارج الحدود
- فائض سعة المخزن المؤقت
- تجاوز عام
معلومات الذاكرة
تصف ما يعرفه 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: |
لا يمكن وصف العنوان | إما خالٍ من الذاكرة (خالٍ من الذاكرة لم يتم تخصيصها من قبل)، أو مجانية مزدوجة بعد التخلص من الذاكرة المخصصة من المخزن المؤقت المجاني لـ 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 بايت من علامات "الإعلان" على اليمين التي تتطابق مع علامة المؤشر).
إذا لم يكن حجم التخصيص من مضاعفات العدد 16، فإن باقي الحجم مخزنة باعتباره memory tag: وسيتم تخزين العلامة كمقطع قصير علامة حبيبات. في المثال أعلاه، بعد التخصيص الغامق الذي تم وضع علامة عليه في الإعلان، لديهم 5 × 16 + 4 = تخصيص 84 بايت للعلامة 5c.
لن يتم حفظ علامة الذاكرة (على سبيل المثال، tags: ad/00 (ptr/mem)
) تشير عادةً إلى
خطأ في استخدام تسلسل استدعاء الدوال البرمجية بعد الإرجاع.
تسجيل تفريغ
يتوافق تفريغ السجل في تقارير HWASan مع التعليمات الفعلية التي أجريت غير صالح معلومة محفوظة الوصول إليه. ثم يتبعه ملف تفريغ سجل آخر من المعالج العادي لإشارات Android. - تجاهل والثاني، يتم استخدامه عندما يسمى HWASan عملية abort() ولا يكون له صلة الخطأ.
الترميز
للحصول على أسماء الدوال وأرقام الأسطر في عمليات تتبع تسلسل استدعاء الدوال البرمجية (والحصول على أسماء المتغيرات لاستخدامها بعد النطاق) الأخطاء)، هناك حاجة إلى خطوة ترميز في وضع عدم الاتصال.
الإعداد لأول مرة: تثبيت أداة ترميز llvm
لإنشاء رمز، يجب تثبيت llvm-Smbolizer في النظام ويمكن الوصول إليه من $PATH. على Debian، يمكنك
عليك تثبيت التطبيق باستخدام sudo apt install llvm
.
الحصول على ملفات الرموز
لأغراض الترميز، نشترط برامج ثنائية غير مجردة تحتوي على رموز. يعتمد مكان العثور عليها على نوع الإصدار:
بالنسبة إلى الإصدارات المحلية، يمكن العثور على ملفات الرموز في
out/target/product/<product>/symbols/
بالنسبة إلى إصدارات AOSP (مثل برنامج Flash من Flashstation)، يجب استخدام
الإصدارات يمكن العثور عليها على Android CI. في "العناصر" بالنسبة إلى
بُنى
سيكون هناك ملف ${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 عندما يتم تحديد نفس المتغير عدة مرات في نفس البرنامج. وهذا يعني أيضًا أنه يتم تدمير المتغير عدة مرات، مما قد يؤدي إلى خطأ "Use-after-free".
بعد الترميز، تُظهر مخالفات سياسة 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، يُرجى الإبلاغ عن خطأ تقديم تعليمات حول كيفية إعادة إظهار المشكلة إن أمكن.