HWAddress Sanitizer

Android NDK hỗ trợ HWAddress Sanitizer, còn được gọi là HWASan, kể từ NDK r21 và Android 10 (API cấp 29). HWASan chỉ có trên các thiết bị Arm 64-bit.

HWASan là một công cụ phát hiện lỗi bộ nhớ tương tự như ASan. So với phiên bản ASan cũ, HWASan có:

  • Mức hao tổn CPU tương tự (~2x)
  • Mức hao tổn kích thước mã tương tự (40 – 50%)
  • Mức hao tổn RAM thấp hơn nhiều (10% – 35%)

HWASan phát hiện cùng một nhóm lỗi như ASan:

  • Chặn tràn (overflow)/chặn trống (underflow) cho ngăn xếp (stack) và bộ nhớ khối xếp (heap)
  • Sử dụng bộ nhớ khối xếp sau khi giải phóng
  • Sử dụng ngăn xếp bên ngoài phạm vi
  • Giải phóng gấp đôi/Giải phóng đối tượng không phải bộ nhớ khối xếp

Ngoài ra, HWASan cũng phát hiện:

  • Sử dụng ngăn xếp sau khi trả về

Thiết lập

Các ứng dụng HWASan cần có một bản dựng HWASan trong Android để chạy. Bạn có thể truyền nhanh hình ảnh HWASan được tạo sẵn sang các thiết bị Pixel được hỗ trợ. Các bản dựng có trên ci.android.com. Tại đây, bạn có thể nhấp vào bản dựng (hình vuông) chính xác mà bạn muốn lấy đường liên kết Bản dựng Flash. Để thực hiện thao tác này, bạn cần biết tên mã cho điện thoại.

Truyền nhanh bản dựng thiết bị

Truy cập thẳng vào flash.android.com có thể dễ dàng hơn vì tại đó, quy trình bắt đầu từ việc phát hiện thiết bị của bạn và chỉ hiển thị các bản dựng mà bạn có thể sử dụng. Các hình ảnh sau minh hoạ quy trình thiết lập trong công cụ này.

Bật chế độ nhà phát triển trên thiết bị của bạn và kết nối với máy tính bằng cáp USB. Nhấp vào Add new device (Thêm thiết bị mới), chọn thiết bị của bạn trong hộp thoại rồi nhấp vào Connect (Kết nối).

Phát hiện thiết bị cần truyền nhanh Chọn thiết bị cần kết nối

Sau khi thiết bị được kết nối, bạn sẽ cần nhấp vào thiết bị đó để định cấu hình bản dựng. Trong hộp Select a build ID (Chọn mã bản dựng), hãy chọn nhánh aosp-master-with-phones-throttled để tự động chọn đúng hình ảnh cho thiết bị bạn đã kết nối.

Chọn thiết bị cần truyền nhanh Xác nhận tuỳ chọn truyền nhanh và truyền nhanh thiết bị

Nhấp vào Install (Cài đặt) để truyền nhanh thiết bị.

Bạn có thể xem thêm thông tin chi tiết về cách thiết lập cần thiết trong tài liệu về Android Flash Tool. Ngoài ra, bạn có thể xem tài liệu về AOSP (Dự án nguồn mở Android) để biết hướng dẫn tạo hình ảnh HWASan từ nguồn.

Tạo

Để tạo mã gốc (JNI) của ứng dụng bằng HWAddress Sanitizer, hãy làm như sau:

ndk-build

Trong tệp 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

Trong tệp build.gradle của mô-đun:

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

Đối với mỗi mục tiêu trong CMakeLists.txt:

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

Chạy

Chạy ứng dụng như bình thường trên hình ảnh Android do HWASan tạo. Khi phát hiện lỗi bộ nhớ, một ứng dụng sẽ gặp sự cố với SIGABRT và đưa ra (print) một thông báo chi tiết tới logcat. Bạn có thể tìm thấy bản sao của thông báo này ở một tệp trong /data/tombstones và bản sao sẽ có dạng như sau:

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)

Theo sau thông báo có thể là thông tin gỡ lỗi bổ sung, chẳng hạn như danh sách các luồng trực tiếp trong ứng dụng, thẻ phân bổ bộ nhớ lân cận, giá trị đăng ký CPU, v.v.