عندما ترصد أداة HWASan خطأ في الذاكرة، يتم إنهاء العملية باستخدام abort()
،
ويتم طباعة تقرير في stderr وlogcat. مثل جميع الأعطال الأصلية على Android، تندرج أخطاء HWASan ضمن /data/tombstones
.
مثال للتقرير
مقارنةً بالأعطال العادية للتطبيقات الأصلية، يحمل HWASan معلومات إضافية في حقل Abort message بالقرب من أعلى رمز الخطأ. في ما يلي مثال على عطل مستند إلى الحِزمة. بالنسبة إلى الأخطاء في الحِزم، يُرجى الاطّلاع على الملاحظة للأقسام المتعلّقة بالحِزم.
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 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: |
|
عدم تطابق علامة الحزمة | لا يفرِّق تقارير "تتبُّع استدعاء الدوال البرمجية" بين أخطاء "القيمة غير الصالحة" و"القيمة غير الصالحة" و أخطاء "الاستخدام بعد الإرجاع". بالإضافة إلى ذلك، للعثور على تعيين الحزمة الذي يمثّل مصدر الخطأ، يجب تنفيذ خطوة ترميز بلا إنترنت. اطّلِع على التعرّف على تقارير ملفّات المشروعات. | |
قيمة غير صالحة لسمة "مجاني" | الاستخدام بعد انتهاء الفترة المجانية | خطأ في ميزة "المساحة الحرة المزدوجة" إذا حدث ذلك عند إيقاف العملية، قد يشير ذلك إلى
انتهاك سياسة حلّ النزاعات من خلال المستخدِمين.
<address> is located N bytes inside of M-byte region [<start>, <end>) freed by thread T0 here: |
لا يمكن وصف العنوان | إما عملية تحرير عشوائية (ذاكرة لم يتم تخصيصها من قبل) أو عملية تحرير مزدوجة بعد إزالة الذاكرة المخصّصة من المخزن المؤقت الحر في HWASan | |
0x... هي ذاكرة احتياطية في HWAsan | حدث خطأ عشوائي، لأنّ التطبيق كان يحاول تحرير ذاكرة داخلية في HWASan. |
تتبُّع تسلسل استدعاء الدوال البرمجية لعمليات إلغاء التخصيص
تتبُّع تسلسل استدعاء الدوال البرمجية لمكان إلغاء تخصيص الذاكرة لا يتم تقديمها إلا للأعطال المتعلّقة بالاستخدام بعد انتهاء الفترة التجريبية أو الأخطاء غير الصالحة. اطّلِع على التصنيف لإضافة تصنيف.
تتبُّع تسلسل استدعاء الدوال البرمجية في حزمة التخصيص
تتبُّع تسلسل استدعاء الدوال البرمجية لمكان تخصيص الذاكرة اطّلِع على التصنيف لإضافة تصنيف.
معلومات متقدّمة عن تصحيح الأخطاء
يعرض تقرير HWASan أيضًا بعض المعلومات المتقدّمة لتصحيح الأخطاء، بما في ذلك (بالترتيب):
- قائمة سلاسل المحادثات في العملية
- قائمة سلاسل المحادثات في العملية
- قيمة علامات الذاكرة بالقرب من الذاكرة التي حدث بها خطأ
- تجميع السجلّات في نقطة الوصول إلى الذاكرة
تفريغ علامة الذاكرة
يمكنك استخدام ملف تخزين الذاكرة للعلامة للبحث عن عمليات تخصيص الذاكرة المجاورة باستخدام العلامة نفسها كعلامة المؤشر. يمكن أن تشير هذه العلامات إلى وصول خارج الحدود مع إزاحة كبيرة. تقابل علامة واحدة 16 بايت من الذاكرة، وتكون علامة المؤشر هي أعلى 8 بت من العنوان. يمكن أن يوفّر ملف تفريغ ذاكرة tag تلميحات، على سبيل المثال، ما يلي هو تدفّق ذاكرة التخزين المؤقت إلى اليمين:
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
، لدينا مساحة مخصّصة للعلامة 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 عندما يتمّ تحديد المتغيّر نفسه عدّة مرّات في البرنامج نفسه. ويعني ذلك أيضًا أنّه يتمّ إلغاء إنشاء المتغيّر عدّة مرات، ما قد يؤدي إلى خطأ 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. يُرجى إبلاغنا بالخطأ وتقديم تعليمات حول كيفية إعادة إنتاج المشكلة إن أمكن.