เมื่อเครื่องมือ 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 สามารถวินิจฉัยสาเหตุต่อไปนี้:
- ใช้หลังจากฟรี
- stack tag-mismatch: นี่อาจเป็น stack use-after-return / use after-scope หรือ out of bounds
- กองบัฟเฟอร์ล้น
- ล้นโลก
ข้อมูลหน่วยความจำ
อธิบายสิ่งที่ 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 ขนาดที่เหลือจะถูกจัดเก็บเป็น แท็กหน่วยความจำ และแท็กจะถูกจัดเก็บเป็น แท็กแบบเม็ดสั้น ในตัวอย่างด้านบนหลังจากโฆษณาที่มีแท็กการจัดสรรเป็นตัวหนา เรามีการจัดสรรแท็ก 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 (เช่น แฟลชจาก 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 ยังสามารถบ่งบอกถึงการละเมิด One Definition Rule (ODR) การละเมิด ODR เกิดขึ้นเมื่อมีการกำหนดตัวแปรเดียวกันหลายครั้งในโปรแกรมเดียวกัน นอกจากนี้ยังหมายความว่าตัวแปรถูกทำลายหลายครั้ง อาจทำให้เกิดข้อผิดพลาด use-after-free
หลังจากสัญลักษณ์ การละเมิด ODR จะแสดง use-after-free ด้วย __cxa_finalize
ทั้งบนสแต็กการเข้าถึงที่ไม่ถูกต้องและสแต็ก "อิสระที่นี่" สแต็ก "ที่จัดสรรไว้ก่อนหน้านี้" มี __dl__ZN6soinfo17call_constructorsEv
และควรชี้ไปที่ตำแหน่งในโปรแกรมของคุณซึ่งกำหนดตัวแปรที่สูงกว่าในสแต็ก
เหตุผลหนึ่งที่ ODR อาจถูกละเมิดคือเมื่อมีการใช้ไลบรารีแบบสแตติก ถ้าสแตติกไลบรารีที่กำหนด C++ global ถูกลิงก์ไปยังไลบรารีที่ใช้ร่วมกันหรือไฟล์เรียกทำงานหลายรายการ คำจำกัดความหลายรายการของสัญลักษณ์เดียวกันอาจลงเอยด้วยการมีอยู่ในพื้นที่ที่อยู่เดียวกัน ซึ่งจะทำให้เกิดข้อผิดพลาด ODR
การแก้ไขปัญหา
"HWAddressSanitizer ไม่สามารถอธิบายที่อยู่โดยละเอียดได้"
บางครั้ง HWASan อาจใช้พื้นที่ไม่เพียงพอสำหรับข้อมูลเกี่ยวกับการจัดสรรหน่วยความจำที่ผ่านมา ในกรณีดังกล่าว รายงานจะมีเพียงสแต็กเทรซเดียวสำหรับการเข้าถึงหน่วยความจำทันที ตามด้วยหมายเหตุ:
HWAddressSanitizer can not describe address in more detail.
ในบางกรณีสามารถแก้ไขได้โดยการรันการทดสอบหลายๆ ครั้ง อีกทางเลือกหนึ่งคือเพิ่มขนาดประวัติ HWASan ซึ่งสามารถทำได้ทั่วโลกใน build/soong/cc/sanitize.go
(มองหา hwasanGlobalOptions
) หรือในสภาพแวดล้อมกระบวนการของคุณ (ลองใช้ adb shell echo $HWASAN_OPTIONS
เพื่อดูการตั้งค่าปัจจุบัน)
"บั๊กที่ซ้อนอยู่ในเธรดเดียวกัน"
ซึ่งหมายความว่ามีข้อบกพร่องขณะสร้างรายงานข้อขัดข้องของ HWASan ซึ่งมักเกิดจากข้อบกพร่องในรันไทม์ HWASan โปรด แจ้งข้อบกพร่อง และให้คำแนะนำเกี่ยวกับวิธีการทำให้เกิดปัญหาซ้ำหากเป็นไปได้