عندما تكتشف أداة 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:
خطأ في الوصول
يحتوي على معلومات حول الوصول السيئ للذاكرة، بما في ذلك:
- نوع الوصول ("قراءة" مقابل "كتابة")
- حجم الوصول (عدد البايتات التي تمت محاولة الوصول إليها)
- رقم الموضوع للوصول
- علامات المؤشر والذاكرة (للتصحيح المتقدم)
الوصول إلى تتبع المكدس
تتبع المكدس للوصول إلى الذاكرة السيئة. راجع قسم الترميز للترميز.
سبب
السبب المحتمل للوصول السيئ. إذا كان هناك عدة مرشحين، يتم إدراجهم بترتيب تنازلي. تسبق المعلومات التفصيلية حول السبب المحتمل. يمكن لـ 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 .. .. .. .. .. .. .. .. .. .. .. .. .. ..(لاحظ تشغيل 6 × 16 = 96 بايت من علامات "الإعلان" الموجودة على اليسار والتي تطابق علامة المؤشر).
إذا لم يكن حجم التخصيص من مضاعفات 16، فسيتم تخزين باقي الحجم كعلامة ذاكرة وسيتم تخزين العلامة كعلامة حبيبية قصيرة . في المثال أعلاه، بعد إعلان التخصيص الغامق مباشرةً، لدينا تخصيص 5 × 16 + 4 = 84 بايت للعلامة 5c.
تشير علامة الذاكرة الصفرية (مثل tags: ad/ 00 (ptr/mem)
) عادةً إلى وجود خطأ في استخدام المكدس بعد العودة.
تسجيل تفريغ
يتوافق تفريغ السجل في تقارير HWASan مع التعليمات الفعلية التي أدت إلى الوصول غير الصالح إلى الذاكرة. يتبعه تفريغ تسجيل آخر من معالج إشارة Android العادي - تجاهل الثاني ، يتم التقاطه عندما يستدعي 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 بتحويل هذا إلى محتوى يمكن فهمه من قبل الإنسان في تقرير الأخطاء، وتتطلب خطوة ترميز إضافية.
انتهاكات تسوية المنازعات على الإنترنت
يمكن أن تشير بعض أخطاء الاستخدام بعد الاستخدام المجانية التي أبلغت عنها 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، يرجى الإبلاغ عن خطأ وتقديم إرشادات حول كيفية إعادة إظهار المشكلة إن أمكن.