فهم تقارير HWASan

عندما ترصد أداة 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: '

[...]

[0x00433ae20040,0x00433ae20060) is a small unallocated heap chunk; size: 32 offset: 5








[ … 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 أيضًا بعض معلومات تصحيح الأخطاء المتقدّمة، بما في ذلك (بالترتيب):

  1. قائمة سلاسل المحادثات في العملية
  2. قائمة سلاسل المحادثات في العملية
  3. قيمة علامات الذاكرة بالقرب من الذاكرة التي حدث فيها الخطأ
  4. تفريغ السجلات في نقطة الوصول إلى الذاكرة

تفريغ علامات الذاكرة

يمكنك استخدام تفريغ علامات الذاكرة للبحث عن تخصيصات الذاكرة القريبة التي تحمل العلامة نفسها كعلامة المؤشر. يمكن أن تشير هذه العلامات إلى وصول خارج النطاق مع إزاحة كبيرة. تتطابق علامة واحدة مع 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. يُرجى الإبلاغ عن خطأ وتقديم تعليمات حول كيفية إعادة إنتاج المشكلة إن أمكن.