HWAddress Sanitizer

Android NDK는 NDK r21 및 Android 10(API 수준 29)부터 HWAddress Sanitizer를 지원합니다.

HWASan은 ASan과 유사한 메모리 오류 감지 도구입니다. HWASan은 기본 ASan과 비교하여 다음과 같은 이점이 있습니다.

  • 유사한 CPU 오버헤드(최대 2배)
  • 유사한 코드 크기 오버헤드(40~50%)
  • RAM 오버헤드가 훨씬 적음(10%~35%)

HWASan은 다음과 같이 ASan과 동일한 버그 집합을 감지합니다.

  • 스택 및 힙 버퍼 오버플로우/언더플로우
  • 프리 후 힙 사용
  • 범위를 벗어난 스택 사용
  • 더블 프리/와일드 프리

또한 HWASan은 다음을 감지합니다.

  • 반환 후 스택 사용

설정

HWASan 애플리케이션을 실행하려면 Android의 HWASan 빌드가 필요합니다. 미리 빌드된 HWASan 이미지를 지원되는 Pixel 기기에 플래시할 수 있습니다. 빌드는 ci.android.com에서 제공되며, 여기에서 플래시 빌드 링크를 얻으려는 정확한 빌드(정사각형)를 클릭하면 됩니다. 이때 휴대전화의 코드명을 알고 있어야 합니다.

기기 빌드 플래시

flash.android.com으로 바로 이동하는 것이 더 쉬울 수 있습니다. 기기 감지와 함께 작업이 시작되고 사용 가능한 빌드만 표시되기 때문입니다. 다음 이미지는 이 도구의 설정 과정을 보여줍니다.

개발자 모드를 사용 설정한 기기를 USB 케이블로 컴퓨터와 연결합니다. 새 기기 추가를 클릭하고 대화상자에서 기기를 선택한 다음 연결을 클릭합니다.

플래시할 기기 감지 연결할 기기 선택

기기가 연결되면 기기를 클릭하여 빌드를 구성해야 합니다. 빌드 ID 선택 상자에서 aosp-master-with-phones-throttled 분기를 선택하여 연결된 기기에 맞는 이미지가 자동으로 선택되도록 합니다.

플래시할 기기 선택 플래시 옵션 확인 및 기기 플래시

설치를 클릭하여 기기를 플래시합니다.

필요한 설정에 관한 자세한 내용은 Android Flash Tool 문서를 참조하세요. 또는 소스에서 HWASan 이미지를 빌드하는 방법은 AOSP 문서를 확인하세요.

빌드

HWAddress Sanitizer를 사용하여 앱의 네이티브(JNI) 코드를 빌드하려면 다음을 따르세요.

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)
set_target_properties(${TARGET} PROPERTIES LINK_FLAGS -fsanitize=hwaddress)

실행

HWASan 기반 Android 이미지에서 평소와 같이 앱을 실행합니다. 메모리 오류가 감지되면 앱이 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 레지스터 값 등의 추가 디버깅 정보가 표시될 수 있습니다.