ตัวล้าง HWAddress

Android NDK รองรับ HWAddress Sanitizer หรือที่เรียกว่า HWASan ตั้งแต่ NDK r21 และ Android 10 (API ระดับ 29) HWASan ใช้ได้เฉพาะในอุปกรณ์ Arm แบบ 64 บิตเท่านั้น

HWASan เป็นเครื่องมือตรวจหาข้อผิดพลาดด้านหน่วยความจําที่คล้ายกับ ASan เมื่อเทียบกับ ASan แบบคลาสสิก HWASan มีดังนี้

  • ภาระงานของ CPU ที่คล้ายกัน (~2 เท่า)
  • ค่าใช้จ่ายเพิ่มเติมเกี่ยวกับขนาดโค้ดที่คล้ายกัน (40 – 50%)
  • การใช้ RAM น้อยลงมาก (10% - 35%)

HWASan จะตรวจหาข้อบกพร่องชุดเดียวกับ ASan ดังนี้

  • บัฟเฟอร์สแต็กและฮีปที่ล้นหรือต่ำกว่าเกณฑ์
  • การใช้งานฮีปหลังจากมีการปลดปล่อย
  • การใช้สแต็กนอกขอบเขต
  • ฟรีแบบคู่หรือฟรีแบบอิสระ

นอกจากนี้ HWASan ยังตรวจหาสิ่งต่อไปนี้ด้วย

  • การใช้กองหลังจากการคืนค่า

แอปตัวอย่าง

แอปตัวอย่างจะแสดงวิธีกำหนดค่าตัวแปรของบิวด์สำหรับ Hwasan

สร้าง

หากต้องการสร้างโค้ดเนทีฟ (JNI) ของแอปด้วย HWAddress Sanitizer ให้ทําดังนี้

ndk-build

ในไฟล์ Application.mk

APP_STL := c++_shared # Or system, or none, but not c++_static.
APP_CFLAGS := -fsanitize=hwaddress -fno-omit-frame-pointer
APP_LDFLAGS := -fsanitize=hwaddress

CMake

ในไฟล์ build.gradle ของโมดูล ให้ทำดังนี้

android {
    defaultConfig {
        externalNativeBuild {
            cmake {
                # Can also use system or none as ANDROID_STL, but not c++_static.
                arguments "-DANDROID_STL=c++_shared"
            }
        }
    }
}

สําหรับแต่ละเป้าหมายใน CMakeLists.txt ให้ทำดังนี้

target_compile_options(${TARGET} PUBLIC -fsanitize=hwaddress -fno-omit-frame-pointer)
target_link_options(${TARGET} PUBLIC -fsanitize=hwaddress)

เมื่อใช้ NDK 27 ขึ้นไป คุณจะใช้สิ่งต่อไปนี้ใน build.gradle ได้โดยไม่ต้องเปลี่ยน CMakeLists.txt

android {
    defaultConfig {
        externalNativeBuild {
            cmake {
                arguments "-DANDROID_SANITIZE=hwaddress"
            }
        }
    }
}

ซึ่งจะไม่ทำงานเมื่อใช้ ANDROID_USE_LEGACY_TOOLCHAIN_FILE=false

Android 14 ขึ้นไป: เพิ่ม wrap.sh

หากใช้ Android 14 ขึ้นไป คุณสามารถใช้สคริปต์ wrap.sh เพื่อเรียกใช้แอปที่แก้ไขข้อบกพร่องได้ในอุปกรณ์ Android เครื่องใดก็ได้ คุณข้ามขั้นตอนนี้ได้หากเลือกที่จะทําตามขั้นตอนในวิธีการตั้งค่า

ทำตามวิธีการเพื่อแพ็กเกจสคริปต์ wrap.sh เพื่อเพิ่มสคริปต์ wrap.sh ต่อไปนี้สำหรับ arm64-v8a

#!/system/bin/sh
LD_HWASAN=1 exec "$@"

เรียกใช้

หากคุณใช้ Android เวอร์ชันเก่ากว่า 14 หรือไม่ได้เพิ่มสคริปต์ wrap.sh ให้ทำตามวิธีการตั้งค่าก่อนเรียกใช้แอป

เรียกใช้แอปตามปกติ เมื่อตรวจพบข้อผิดพลาดด้านหน่วยความจำ แอปจะขัดข้องด้วย SIGABRT และพิมพ์ข้อความโดยละเอียดไปยัง Logcat สำเนาข้อความจะอยู่ในไฟล์ในส่วน /data/tombstones และมีลักษณะดังนี้

ERROR: HWAddressSanitizer: tag-mismatch on address 0x0042a0826510 at pc 0x007b24d90a0c
WRITE of size 1 at 0x0042a0826510 tags: 32/3d (ptr/mem) in thread T0
    #0 0x7b24d90a08  (/data/app/com.example.hellohwasan-eRpO2UhYylZaW0P_E0z7vA==/lib/arm64/libnative-lib.so+0x2a08)
    #1 0x7b8f1e4ccc  (/apex/com.android.art/lib64/libart.so+0x198ccc)
    #2 0x7b8f1db364  (/apex/com.android.art/lib64/libart.so+0x18f364)
    #3 0x7b8f2ad8d4  (/apex/com.android.art/lib64/libart.so+0x2618d4)

0x0042a0826510 is located 0 bytes to the right of 16-byte region [0x0042a0826500,0x0042a0826510)
allocated here:
    #0 0x7b92a322bc  (/apex/com.android.runtime/lib64/bionic/libclang_rt.hwasan-aarch64-android.so+0x212bc)
    #1 0x7b24d909e0  (/data/app/com.example.hellohwasan-eRpO2UhYylZaW0P_E0z7vA==/lib/arm64/libnative-lib.so+0x29e0)
    #2 0x7b8f1e4ccc  (/apex/com.android.art/lib64/libart.so+0x198ccc)

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

ดูข้อมูลเพิ่มเติมเกี่ยวกับข้อความแสดงข้อผิดพลาด HWASan ได้ที่การทำความเข้าใจรายงาน HWASan

การสร้างไฟล์ปฏิบัติการของบรรทัดคำสั่ง

คุณสามารถสร้างและเรียกใช้ไฟล์ปฏิบัติการที่เครื่องมือวัดประสิทธิภาพ HWASan ตรวจสอบแล้วใน Android 14 ขึ้นไป คุณใช้การกำหนดค่าเดียวกันกับที่อธิบายไว้ในการสร้างสำหรับ ndk-build หรือ CMake สำหรับไฟล์ปฏิบัติการได้ พุชไฟล์ที่เรียกใช้งานได้ไปยังอุปกรณ์ที่ใช้ Android 14 ขึ้นไป แล้วเรียกใช้ตามปกติโดยใช้เชลล์

หากคุณใช้ libc++ ให้ตรวจสอบว่าคุณใช้ STL ที่แชร์และพุชไปยังอุปกรณ์ รวมถึงตั้งค่า LD_LIBRARY_PATH เป็นไดเรกทอรีที่มี STL ดังกล่าวเมื่อเรียกใช้ไบนารี

หากคุณไม่ได้ใช้ Gradle โปรดดูเอกสารประกอบ NDK เพื่อดูวิธีสร้างจากบรรทัดคำสั่งด้วย CMake และ ndk-build

Android 13 หรือเวอร์ชันก่อนหน้า: การตั้งค่า

หากอุปกรณ์ใช้ Android 14 ขึ้นไป คุณสามารถข้ามขั้นตอนนี้และทำตามวิธีการใช้ wrap.sh ในส่วนสร้าง นอกจากนี้ คุณยังเลือกที่จะทำตามส่วนนี้และข้ามวิธีการใช้ wrap.sh ได้ด้วย

ก่อนที่จะเป็น Android 14 แอปพลิเคชัน HWASan ต้องใช้ Android รุ่น HWASan จึงจะทำงานได้ คุณสามารถแฟลชอิมเมจ HWASan ที่คอมไพล์ไว้ล่วงหน้าลงในอุปกรณ์ Pixel ที่รองรับ บิลด์มีให้บริการใน ci.android.com ซึ่งคุณสามารถคลิกสี่เหลี่ยมจัตุรัสของบิลด์ที่ต้องการเพื่อรับลิงก์บิลด์แฟลช ซึ่งคุณจะต้องทราบชื่อรหัสของโทรศัพท์

แฟลชบิลด์อุปกรณ์

คุณอาจไปที่ flash.android.com โดยตรงจะง่ายกว่า เนื่องจากขั้นตอนเริ่มต้นด้วยการสแกนอุปกรณ์และแสดงเฉพาะบิลด์ที่คุณใช้ได้ รูปภาพต่อไปนี้แสดงขั้นตอนการตั้งค่าในเครื่องมือนี้

เปิดใช้โหมดนักพัฒนาแอปในอุปกรณ์และเชื่อมต่อกับคอมพิวเตอร์โดยใช้สาย USB คลิกเพิ่มอุปกรณ์ใหม่ เลือกอุปกรณ์จากกล่องโต้ตอบ แล้วคลิกเชื่อมต่อ

ตรวจหาอุปกรณ์ที่จะกะพริบ เลือกอุปกรณ์ที่จะเชื่อมต่อ

หลังจากเชื่อมต่ออุปกรณ์แล้ว ให้คลิกอุปกรณ์เพื่อกำหนดค่าบิลด์ ในช่องเลือกรหัสบิลด์ ให้เลือกสาขา aosp-master-with-phones-throttled เพื่อเลือกรูปภาพที่ถูกต้องสำหรับอุปกรณ์ที่คุณเชื่อมต่อโดยอัตโนมัติ

เลือกอุปกรณ์ที่จะแฟลช ยืนยันตัวเลือกแฟลชแล้วแฟลชอุปกรณ์

คลิกติดตั้งเพื่อแฟลชอุปกรณ์

ดูรายละเอียดเพิ่มเติมเกี่ยวกับการตั้งค่าที่จำเป็นได้ในเอกสารประกอบเกี่ยวกับเครื่องมือแฟลช Android หรือจะดูวิธีการสร้างภาพ HWASan จากแหล่งที่มาในเอกสารประกอบ AOSP ก็ได้