عندما ترصد أداة HWASan خطأ في الذاكرة، يتم إنهاء العملية باستخدام abort()، ويتم طباعة تقرير في stderr وlogcat. مثل جميع الأعطال الأصلية على Android، تندرج أخطاء HWASan ضمن /data/tombstones.
مثال للتقرير
مقارنةً بالأعطال الأصلية العادية، تتضمّن أداة HWASan معلومات إضافية في حقل رسالة الإيقاف بالقرب من أعلى ملف tombstone. في ما يلي نموذج لعطل يستند إلى الذاكرة المؤقتة. بالنسبة إلى أخطاء حزمة البيانات، يُرجى الاطّلاع على الـ ملاحظة الخاصة بأقسام حزمة البيانات.
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 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: |
| لا يمكن وصف العنوان | إما تحرير عشوائي (تحرير ذاكرة لم يتم تخصيصها من قبل) أو تحرير مزدوج بعد إخلاء الذاكرة المخصّصة من المخزن المؤقت المجاني لأداة 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 .. .. .. .. .. .. .. .. .. .. .. .. .. ..
يُرجى العِلم بتسلسل علامات ad لـ 6 × 16 = 96 بايت على يسار العلامة التي تتطابق مع علامة المؤشر.
إذا لم يكن حجم التخصيص من مضاعفات الرقم 16، يتم تخزين الجزء المتبقي من الحجم كـ
علامة الذاكرة ويتم تخزين العلامة كـ علامة حبيبة
قصيرة. في المثال السابق، بعد التخصيص الذي تم وضع علامة ad عليه بالخط العريض مباشرةً، لدينا تخصيص بعلامة 5c بحجم 5 × 16 + 4 = 84 بايت.
تشير علامة الذاكرة الصفرية (على سبيل المثال، tags: ad/00 (ptr/mem)) إلى خطأ في استخدام حزمة البيانات بعد إرجاعها.
تفريغ السجلات
يتطابق تفريغ السجلات في تقارير HWASan مع التعليمات التي نفّذت الوصول غير الصالح إلى الذاكرة. يتبع هذا التفريغ تفريغ سجلات آخر من معالج الإشارات العادي في Android. يُرجى تجاهل التفريغ الثاني، لأنّه تم أخذه عندما استدعت أداة HWASan الدالة
abort() وليس له صلة بالخطأ.
وضع الرموز
للحصول على أسماء الدوال وأرقام الأسطر في تقارير تتبُّع تسلسل استدعاء الدوال البرمجية (والحصول على أسماء المتغيّرات لأخطاء الاستخدام بعد النطاق)، يجب تنفيذ خطوة وضع الرموز بلا إنترنت.
الإعداد للمرة الأولى: تثبيت llvm-symbolizer
لوضع الرموز، يجب أن يكون نظامك مثبّتًا عليه llvm-symbolizer ويمكن الوصول إليه من $PATH. على Debian، يمكنك تثبيته باستخدام sudo apt install llvm.
الحصول على ملفات الرموز
لوضع الرموز، نحتاج إلى ملفات ثنائية غير مجرّدة تحتوي على رموز. يعتمد موقعها على نوع الإصدار:
- بالنسبة إلى الإصدارات المحلية، تكون ملفات الرموز في
out/target/product/<product>/symbols/. - بالنسبة إلى إصدارات AOSP (على سبيل المثال، التي تم تنزيلها من
Android Flash Tool)، تكون
الإصدارات على 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) عندما يتم تعريف المتغيّر نفسه عدة مرات في البرنامج نفسه. يعني ذلك أيضًا أنّه يتم تدمير المتغيّر عدة مرات، ما قد يؤدي إلى خطأ الاستخدام بعد التحرير.
بعد وضع الرموز، تعرض انتهاكات قاعدة التعريف الواحد (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 بشكل عام. إذا كان بإمكانك الوصول إلى ملف tombstone الكامل، قد يكون من المفيد الاطّلاع على تفريغ خرائط الذاكرة لمعرفة عملية الربط (إن وُجدت) التي ينتمي إليها العنوان.
خطأ متداخل في سلسلة المحادثات نفسها
يعني ذلك أنّه حدث خطأ أثناء إنشاء تقرير عطل HWASan. يرجع ذلك عادةً إلى خطأ في وقت تشغيل HWASan. يُرجى الإبلاغ عن خطأ وتقديم تعليمات حول كيفية إعادة إنتاج المشكلة إن أمكن.