Address Sanitizer를 사용한 메모리 손상 디버그

이 문서에서는 AGDE를 사용할 때 특수 디버깅 도구를 사용 설정하는 방법을 보여줍니다. 이러한 도구는 진단하기 어려운 메모리 손상 및 덮어쓰기 오류를 디버깅하는 데 도움이 될 수 있습니다.

HWAddress Sanitizer 및 Address Sanitizer

HWAddress Sanitizer(HWASan) 및 Address Sanitizer(ASan)는 다음과 같은 메모리 손상 및 덮어쓰기 오류를 디버깅하는 데 도움이 되는 메모리 손상 디버깅 도구입니다.

  • 스택 버퍼 오버플로 및 언더플로
  • 힙 버퍼 오버플로 및 언더플로
  • 범위를 벗어난 스택 사용
  • 더블 프리 및 와일드 프리 오류
  • 반환 후 스택 사용(HWASan만 해당)

HWASan 또는 ASan은 문제를 디버깅할 때나 자동 테스트의 일부로만 사용 설정하는 것이 좋습니다. 이들 도구는 성능이 우수하지만 사용할 경우 불이익이 발생합니다.

런타임 동작

HWASan 및 ASan은 사용 설정되면 앱의 전체 런타임 동안 메모리 손상이 있는지 자동으로 확인합니다.

메모리 오류가 감지되면 앱이 SIGBART(신호 중단) 오류와 함께 비정상 종료되고 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)

기본 요건

Android OS의 HWASan 빌드 설치

HWASan을 사용하려면 HWASan 문서의 설정 안내에 따라 Google Pixel 기기용 Android OS의 HWASan 빌드를 설치합니다.

다른 기기의 경우 제조업체에 문의하여 OS의 HWASan 빌드를 받거나(있는 경우), 소프트웨어 전용 ASan 도구를 사용합니다.

프로젝트에서 공유 C++ 표준 라이브러리 사용

알려진 문제로 인해, ASan은 libc++_static 사용 시 C++ 예외 처리와 호환되지 않습니다. libc++_shared를 사용하는 경우에는 이 문제가 나타나지 않습니다.

HWASan에는 연산자 newdelete가 자체적으로 구현되어 있는데, 이러한 연산자는 표준 라이브러리가 프로젝트에 정적으로 연결된 경우 사용할 수 없습니다.

이 설정을 변경하려면 이 문서의 C++ 표준 라이브러리 연결 섹션을 참고하세요.

프레임 포인터 생성 사용 설정

HWASan 및 ASan은 빠른 프레임 포인터 기반 언와인더를 사용하여 메모리 할당 및 할당 해제 이벤트의 스택 트레이스 정보를 생성합니다. 즉, 이러한 기능을 사용하려면 C++ 컴파일러 설정에서 프레임 포인터 생성을 사용 설정해야 합니다. 다시 말하면, 프레임 포인터 생략 최적화를 사용 중지해야 합니다.

이 설정을 변경하려면 이 문서의 프레임 포인터 생성 사용 설정 섹션을 참고하세요.

HWASan 또는 ASan을 사용하도록 Visual Studio 프로젝트 구성

HWASan 또는 ASan 사용 설정

HWASan 또는 ASan을 사용 설정하려면 프로젝트의 속성 페이지에서 구성 속성 > 일반으로 이동합니다.

현재 프로젝트의 Visual Studio 솔루션 탐색기 속성 메뉴

그림 1: Visual Studio 솔루션 탐색기 창에 있는 프로젝트의 속성 옵션

일반 속성이 표시되어 있고 Address Sanitizer 설정이 강조표시되어 있는 프로젝트 속성 페이지 대화상자.

그림 2: 일반 프로젝트 속성의 Address Sanitizer(ASan) 설정

프로젝트에서 HWASan을 사용 설정하려면 Address Sanitizer(ASan) 설정을 Hardware ASan 사용(fsanitize=hwaddress)으로 변경합니다.

프로젝트에서 ASan을 사용 설정하려면 Address Sanitizer(ASan) 설정을 ASan 사용(fsanitize=address)으로 변경합니다.

프레임 포인터 생성 사용 설정

프레임 포인터 생성은 프레임 포인터 생략 C/C++ 컴파일러 설정에 의해 제어되며 프로젝트 속성 페이지구성 속성 > C/C++ > 최적화에서 찾을 수 있습니다.

C/C++ 최적화 속성이 표시되어 있고 프레임 포인터 생략 설정이 강조표시되어 있는 프로젝트 속성 페이지 대화상자.

그림 3: 프레임 포인터 생략 설정을 찾을 수 있는 위치

HWASan 또는 ASan을 사용할 때는 프레임 포인터 생략 설정을 아니요(-fno-omit-frame-pointer)로 설정합니다.

공유 라이브러리 모드에서 C++ 표준 라이브러리 연결

C++ 표준 라이브러리의 링커 모드 설정은 프로젝트 속성 페이지구성 속성 > 일반프로젝트 기본값 섹션에서 찾을 수 있습니다.

일반 카테고리가 선택되어 있고 STL 사용 설정이 강조표시되어 있는 프로젝트 속성 페이지 대화상자.

그림 4: C++ 표준 라이브러리의 링커 모드 설정을 찾을 수 있는 위치

HWASan 또는 ASan을 사용할 때는 STL 사용C++ 표준 라이브러리(.so) 사용으로 설정합니다. 이 값은 C++ 표준 라이브러리를 프로젝트에 공유 라이브러리로 연결합니다. 이는 HWASan 및 ASan이 올바르게 작동하는 데 필요합니다.

Address Sanitizer 사용을 위해 빌드 구성 만들기

HWASan 또는 ASan을 일시적으로 사용하려면 이러한 기능을 사용하기 위한 구성을 새로 만드는 것이 번거로울 수 있습니다. 프로젝트가 작거나, 기능을 살펴보는 중이거나, 테스트 중에 발견한 문제에 대응하는 경우가 이러한 상황에 해당할 수 있습니다.

반면에 이 기능이 유용하다고 판단되어 정기적으로 사용하고 싶다면 Teapot 샘플에 나와 있는 것처럼 HWASan 또는 ASan의 새 빌드 구성을 만드는 것이 좋습니다. 예를 들어, 단위 테스트의 일환으로 또는 게임의 야간 스모크 테스트 중에 Address Sanitizer를 정기적으로 실행할 수 있습니다.

별도의 빌드 구성을 만드는 것은 일반적으로 C++ 표준 라이브러리와 정적으로 연결하는 서드 파티 라이브러리를 많이 사용하는 대규모 프로젝트에 특히 유용합니다. 전용 빌드 구성을 만들면 프로젝트 설정을 항상 정확하게 유지할 수 있습니다.

빌드 구성을 만들려면 프로젝트 속성 페이지에서 구성 관리자... 버튼을 클릭한 후 활성 솔루션 구성 드롭다운을 엽니다. 그런 다음 를 선택하고 적절한 이름으로 새 빌드 구성을 만듭니다(예: HWASan 사용).