فهم تقارير HWASan

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

[...]

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








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

  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  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..
(يُرجى ملاحظة تشغيل 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، يُرجى الإبلاغ عن خطأ تقديم تعليمات حول كيفية إعادة إظهار المشكلة إن أمكن.