ทำความเข้าใจรายงาน HWASan

เมื่อเครื่องมือ HWASan ตรวจพบข้อบกพร่องด้านหน่วยความจํา ระบบจะยุติกระบวนการด้วย abort() และ รายงานจะถูกพิมพ์ไปยัง stderr และ Logcat ข้อผิดพลาด HWASan อาจเกิดขึ้นเช่นเดียวกับข้อขัดข้องของระบบทั้งหมดใน Android พบภายใต้ /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 เกือบทั้งหมดเป็นแบบ "tag-mismatch" กล่าวคือ การเข้าถึงหน่วยความจำเมื่อแท็กตัวชี้ทำ ไม่ตรงกับแท็กหน่วยความจำที่เกี่ยวข้อง ซึ่งอาจเป็นหนึ่งใน

  • การเข้าถึงนอกขอบเขตบนสแต็กหรือฮีป
  • ใช้หลังจากฟรีในฮีป
  • ใช้หลังจากส่งคืนในสแต็ก

ส่วน

ด้านล่างนี้คือคำอธิบายแต่ละส่วนของรายงาน HWASan

ข้อผิดพลาดในการเข้าถึง

มีข้อมูลเกี่ยวกับการเข้าถึงหน่วยความจําที่ไม่ถูกต้อง ได้แก่

  • ประเภทการเข้าถึง ("READ" กับ "WRITE")
  • ขนาดการเข้าถึง (จำนวนไบต์ที่มีการเข้าถึง)
  • หมายเลขชุดข้อความของการเข้าถึง
  • แท็กตัวชี้และหน่วยความจำ (สำหรับการแก้ไขข้อบกพร่องขั้นสูง)

เข้าถึงสแต็กเทรซ

สแต็กเทรซของการเข้าถึงหน่วยความจำที่ไม่ถูกต้อง ดูส่วนสัญลักษณ์เพื่อ เป็นสัญลักษณ์

สาเหตุ

สาเหตุที่อาจทำให้เกิดการเข้าถึงที่ไม่ดี หากมีผู้สมัครหลายคน คือ แสดงตามลำดับจากมากไปน้อย อยู่ข้างหน้าข้อมูลโดยละเอียดเกี่ยวกับ สาเหตุที่เป็นไปได้ HWASan สามารถวินิจฉัยสาเหตุต่อไปนี้

  • ใช้หลังใช้ฟรี
  • Stack Tag-mismatch: อาจเป็นสแต็ก "ใช้หลังการส่งคืน"/"ใช้หลังขอบเขต" หรือ อยู่นอกขอบเขต
  • การล้นฮีปบัฟเฟอร์
  • การทำงานเพิ่มเติมทั่วโลก

ข้อมูลหน่วยความจำ

อธิบายสิ่งที่ 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:
แท็กสแต็กไม่ตรงกัน รายงานสแต็กจะไม่แยกความแตกต่างระหว่างรายการเพิ่มเติม/การดำเนินการน้อยกับ ข้อบกพร่องการใช้งานหลังการส่งคืน ใน นอกจากนี้ หากต้องการค้นหาการจัดสรรสแต็ก ที่เป็นแหล่งที่มาของข้อผิดพลาด ออฟไลน์ ต้องระบุขั้นตอนการแทนที่ด้วยสัญลักษณ์ โปรดดูการทำความเข้าใจรายงานสแต็ก ด้านล่าง
ไม่มีที่ไม่ถูกต้อง ใช้หลังใช้ฟรี นี่คือข้อบกพร่องแบบ 2 เท่า หากเกิดกรณีนี้ขึ้นตอนการปิดกระบวนการ นั่นอาจหมายถึง การละเมิด 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. ดัมพ์ของการลงทะเบียน ณ จุดที่มีการเข้าถึงหน่วยความจำ

ดัมพ์แท็กหน่วยความจำ

ดัมพ์ของหน่วยความจำแท็กสามารถใช้เพื่อค้นหาการจัดสรรหน่วยความจำใกล้เคียงที่มีแท็กเดียวกัน ในฐานะ Pointer แท็ก สิ่งเหล่านี้อาจชี้ไปยังการเข้าถึงนอกขอบเขตที่มีออฟเซ็ตขนาดใหญ่ 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  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..
(โปรดทราบว่าการเรียกใช้แท็ก "โฆษณา" ขนาด 6 × 16 = 96 ไบต์ทางด้านซ้ายซึ่งตรงกับแท็กตัวชี้)

หากขนาดของการจัดสรรไม่ใช่ผลคูณของ 16 ขนาดที่เหลือจะเป็น จัดเก็บแล้ว ในฐานะ แท็กหน่วยความจำ และระบบจะบันทึกแท็กเป็น short Granule ในตัวอย่างข้างต้นหลังจากติดแท็กการจัดสรรที่เป็นตัวหนาแล้ว โฆษณา มี 5 × 16 + 4 = การจัดสรร 84 ไบต์ของแท็ก 5c

แท็กหน่วยความจำศูนย์ (เช่น 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 (เช่น แฟลชจาก 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 เกิดขึ้นเมื่อมีการกำหนดตัวแปรเดียวกันหลายครั้งในโปรแกรมเดียวกัน และยังหมายความว่าตัวแปรถูกทำลายหลายครั้ง ซึ่งอาจทำให้ ข้อผิดพลาดการใช้งานหลังใช้ฟรี

หลังจากการแทนที่ด้วยสัญลักษณ์ การละเมิด ODR จะแสดงการใช้งานหลังใช้ฟรีกับ __cxa_finalize ทั้งสแต็กการเข้าถึงที่ไม่ถูกต้องและ "อิสระที่นี่" สแต็ก "การจัดสรรก่อนหน้านี้ ที่นี่" สแต็กมี __dl__ZN6soinfo17call_constructorsEv และควร ที่ตำแหน่งในโปรแกรมซึ่งกำหนดตัวแปรที่อยู่สูงขึ้นในกลุ่ม

เหตุผลหนึ่งที่อาจละเมิด ODR คือเมื่อมีการใช้ไลบรารีแบบคงที่ หากไลบรารีแบบคงที่ซึ่งกำหนด C++ ส่วนกลางลิงก์กับไลบรารีที่ใช้ร่วมกันหลายรายการ หรือ ไฟล์ปฏิบัติการ การกำหนดสัญลักษณ์ที่เหมือนกันหลายรายการอาจรวมอยู่ในที่อยู่เดียวกัน ที่ว่างอยู่ ซึ่งจะทำให้เกิดข้อผิดพลาด ODR

การแก้ปัญหา

HWAddressSanitizer ไม่สามารถอธิบายที่อยู่อย่างละเอียด

บางครั้ง HWASan อาจมีพื้นที่ว่างสำหรับข้อมูลเกี่ยวกับการจัดสรรหน่วยความจำที่ผ่านมาจนหมด ในกรณีดังกล่าว รายงาน จะมีสแต็กเทรซเพียง 1 รายการสำหรับการเข้าถึงหน่วยความจำทันที ตามด้วยหมายเหตุต่อไปนี้

  HWAddressSanitizer can not describe address in more detail.

ในบางกรณี ปัญหานี้สามารถแก้ไขได้โดยทำการทดสอบหลายๆ ครั้ง อีกทางเลือกหนึ่งคือการเพิ่ม HWASan ขนาดที่ผ่านมา ซึ่งทำได้ทั่วโลกใน build/soong/cc/sanitize.go (มองหา hwasanGlobalOptions) หรือในสภาพแวดล้อมกระบวนการ (ลอง adb shell echo $HWASAN_OPTIONS เพื่อดูการตั้งค่าปัจจุบัน)

กรณีนี้อาจเกิดขึ้นหากหน่วยความจำที่เข้าถึงไม่ได้รับการแมปหรือจัดสรรโดยการรับรู้ที่ไม่ใช่ HWAS ผู้จัดสรร ในกรณีนี้ แท็ก mem ที่แสดงในส่วนหัวของข้อขัดข้องมัก 00 หากคุณสามารถเข้าถึง Tombstone ฉบับเต็มได้ ขอแนะนำให้คุณปรึกษา Dump การแมปหน่วยความจำเพื่อค้นหาว่าที่อยู่นั้นเป็นของการแมปใด (หากมี)

ข้อบกพร่องที่ซ้อนกันในชุดข้อความเดียวกัน

ซึ่งหมายความว่ามีข้อบกพร่องขณะสร้างรายงานข้อขัดข้องของ HWASan ซึ่งโดยปกติจะเกิดจากข้อบกพร่องใน รันไทม์ของ HWASan โปรดรายงานข้อบกพร่อง และ ให้คำแนะนำเกี่ยวกับวิธีทำให้ปัญหาเกิดซ้ำหากเป็นไปได้