เมื่อเครื่องมือ HWASan ตรวจพบจุดบกพร่องของหน่วยความจำ กระบวนการจะสิ้นสุดลงด้วยการยกเลิก () และรายงานจะถูกพิมพ์ไปยัง 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 .. .. .. .. .. .. .. .. .. .. .. .. .. ..(สังเกตการทำงานของแท็ก "ad" ทางด้านซ้ายขนาด 6 × 16 = 96 ไบต์ซึ่งตรงกับแท็กตัวชี้)
หากขนาดของการจัดสรรไม่เป็นทวีคูณของ 16 ขนาดส่วนที่เหลือจะถูกจัดเก็บเป็น แท็กหน่วยความจำ และแท็กจะถูกจัดเก็บเป็น แท็กแกรนูลขนาดสั้น ในตัวอย่างด้านบนหลังจากโฆษณาที่ติดแท็กการจัดสรรด้วยตัวหนา เรามีการจัดสรรแท็ก 5c ขนาด 5 × 16 + 4 = 84 ไบต์
แท็กหน่วยความจำเป็นศูนย์ (เช่น tags: ad/ 00 (ptr/mem)
) มักจะบ่งชี้ถึงข้อบกพร่องในการใช้สแต็กหลังการส่งคืน
ลงทะเบียนการถ่ายโอนข้อมูล
การถ่ายโอนข้อมูลการลงทะเบียนในรายงาน HWASan สอดคล้องกับคำสั่งจริงที่ทำการเข้าถึงหน่วยความจำที่ไม่ถูกต้อง ตามมาด้วย register dump อื่นจากตัวจัดการสัญญาณ Android ปกติ - ไม่ต้องสนใจอันที่สอง ซึ่งจะถูกนำไปใช้เมื่อ HWASan เรียกว่า abort() และไม่เกี่ยวข้องกับจุดบกพร่อง
การแสดงสัญลักษณ์
หากต้องการรับชื่อฟังก์ชันและหมายเลขบรรทัดในการติดตามสแต็ก (และรับชื่อตัวแปรสำหรับจุดบกพร่องการใช้งานหลังขอบเขต) จำเป็นต้องมีขั้นตอนการแสดงสัญลักษณ์แบบออฟไลน์
การตั้งค่าครั้งแรก: ติดตั้ง llvm-สัญลักษณ์
หากต้องการแสดงสัญลักษณ์ ระบบของคุณต้องติดตั้ง llvm- Symbolizer และเข้าถึงได้จาก $PATH บน Debian คุณสามารถติดตั้งได้โดยใช้ sudo apt install llvm
รับไฟล์สัญลักษณ์
สำหรับการแสดงสัญลักษณ์ เราต้องการไบนารีที่ยังไม่ได้แยกซึ่งมีสัญลักษณ์ ตำแหน่งที่สามารถพบได้จะขึ้นอยู่กับประเภทของบิลด์:
สำหรับ บิลด์โลคัล ไฟล์สัญลักษณ์สามารถพบได้ใน out/target/product/<product>/symbols/
สำหรับ บิลด์ AOSP (เช่น flashed จาก Flashstation ) บิลด์สามารถพบได้บน Android CI ใน "อาร์ติแฟกต์" สำหรับบิลด์ จะมีไฟล์ `${PRODUCT}-สัญลักษณ์-${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 แสดง use-after-free ด้วย __cxa_finalize
ทั้งบนสแต็กการเข้าถึงที่ไม่ถูกต้องและสแต็ก "freed here" สแต็ก "จัดสรรไว้ก่อนหน้านี้ที่นี่" มี __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 โปรด แจ้งจุดบกพร่อง และให้คำแนะนำเกี่ยวกับวิธีการทำให้เกิดปัญหาอีกครั้งหากเป็นไปได้