เมื่อเครื่องมือ HWASan ตรวจพบข้อบกพร่องด้านหน่วยความจำ ระบบจะสิ้นสุดกระบวนการด้วย abort()
และพิมพ์รายงานไปยัง stderr และ logcat ข้อผิดพลาด HWASan จะอยู่ใน/data/tombstones
เช่นเดียวกับข้อผิดพลาดข้อขัดข้องทั้งหมดในเนทีฟบน Android
รายงานตัวอย่าง
เมื่อเทียบกับข้อขัดข้องทั่วไปของระบบ HWASan จะมีข้อมูลเพิ่มเติมในช่องAbort message ใกล้กับด้านบนของรายการ ตัวอย่างข้อขัดข้องที่เกิดในฮีปมีดังนี้ สำหรับข้อบกพร่องของกอง โปรดดูหมายเหตุสำหรับส่วนเฉพาะของกอง
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 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
ข้อผิดพลาดในการเข้าถึง
มีข้อมูลเกี่ยวกับการเข้าถึงหน่วยความจำที่ไม่ถูกต้อง ซึ่งรวมถึงข้อมูลต่อไปนี้
- ประเภทการเข้าถึง (
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: |
อธิบายที่อยู่ไม่ได้ | อาจเป็น Free ที่ไม่ถูกต้อง (หน่วยความจำที่ไม่มีการจัดสรรมาก่อน) หรือ Free ซ้ำหลังจากที่หน่วยความจำที่จัดสรรถูกนำออกจากบัฟเฟอร์ว่างของ HWASan | |
0x... คือหน่วยความจำเงาของ HWAsan | หน่วยความจําที่ปล่อยออกมาอย่างอิสระ เนื่องจากแอปพยายามที่จะเพิ่มพื้นที่ว่างในหน่วยความจําภายใน HWASan |
สแต็กเทรซการยกเลิกการจัดสรร
สแต็กเทรซของตำแหน่งที่มีการยกเลิกการจัดสรรหน่วยความจำ แสดงเฉพาะสำหรับข้อบกพร่องการใช้หลังจากยกเลิกการจองหรือข้อบกพร่องที่ไม่เป็นโมฆะ ดูการกำหนดสัญลักษณ์เพื่อกำหนดสัญลักษณ์
สแต็กเทรซการจัดสรร
สแต็กเทรซของตำแหน่งที่มีการจัดสรรหน่วยความจำ ดูการกำหนดสัญลักษณ์เพื่อกำหนดสัญลักษณ์
ข้อมูลการแก้ไขข้อบกพร่องขั้นสูง
รายงาน HWASan ยังมีข้อมูลการแก้ไขข้อบกพร่องขั้นสูงบางอย่างด้วย ซึ่งได้แก่ (เรียงตามลําดับ)
- รายการเธรดในกระบวนการ
- รายการเธรดในกระบวนการ
- ค่าของแท็กหน่วยความจําที่อยู่ใกล้กับหน่วยความจําที่ขัดข้อง
- การดัมพ์รีจิสเตอร์ ณ จุดที่เข้าถึงหน่วยความจำ
ดัมพ์แท็กหน่วยความจำ
คุณสามารถใช้การดัมพ์หน่วยความจําของแท็กเพื่อค้นหาการจัดสรรหน่วยความจําที่อยู่ใกล้เคียงซึ่งมีแท็กเดียวกับแท็กพอยน์เตอร์ แท็กเหล่านี้อาจชี้ไปที่การเข้าถึงที่อยู่นอกขอบเขตโดยมีออฟเซตขนาดใหญ่ แท็ก 1 รายการจะสอดคล้องกับหน่วยความจำ 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 ระบบจะจัดเก็บส่วนที่เหลือของขนาดเป็นแท็กหน่วยความจํา และจัดเก็บแท็กเป็นแท็ก Granule แบบสั้น ในตัวอย่างก่อนหน้านี้ ถัดจากการกําหนดค่าแบบตัวหนาที่ติดแท็ก ad
เรามีการจัดสรรแท็ก 5c
เป็น 5 × 16 + 4 = 84 ไบต์
แท็กหน่วยความจำเป็น 0 (เช่น tags: ad/00 (ptr/mem)
) บ่งบอกถึงข้อบกพร่องการใช้สแต็กหลังจากการคืนค่า
ดัมพ์รีจิสทรี
การดัมพ์รีจิสเตอร์ในรายงาน HWASan สอดคล้องกับคำสั่งที่ดำเนินการเข้าถึงหน่วยความจำที่ไม่ถูกต้อง การดัมพ์นี้ตามด้วยการดัมพ์รีจิสเตอร์อีกรายการจากตัวแฮนเดิลสัญญาณ Android ปกติ ละเว้นการดัมพ์ที่ 2 เนื่องจากเป็นการดัมพ์เมื่อ 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
ทั้งในสแต็กการเข้าถึงที่ไม่ถูกต้องและสแต็กปลดปล่อยที่นี่ กอง previously
allocated 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 รายงานข้อบกพร่องและระบุวิธีการทําให้ปัญหาเกิดซ้ำ (หากเป็นไปได้)