Debugowanie uszkodzenia pamięci za pomocą narzędzia Address Sanitizer

W tym dokumencie opisujemy, jak włączyć specjalne narzędzia do debugowania w przypadku użycia AGDE. Narzędzia te pomagają w przypadku trudnych do zdiagnozowania uszkodzeń pamięci i błędów nadpisywania.

Preparat do dezynfekcji adresów i HWAddress

HWAddress Sanitizer (HWASan) i Address Sanitizer (ASan) to narzędzia do debugowania uszkodzonego pamięci i błędów związanych z nadużyciem, takie jak:

  • Przepełnienia i niedopełnienie bufora stosu
  • Przepełnienia i niedopełnienia bufora sterty
  • Użycie stosu poza jego zakresem
  • Podwójne błędy typu wilgotne
  • Użycie stosu po zwrocie (tylko HWASan)

Zalecamy włączanie kodu HWASan lub ASan tylko wtedy, gdy debugujesz problem lub w ramach automatycznego testowania. Chociaż narzędzia te są skuteczne, ich używanie wiąże się z karą.

Działanie środowiska wykonawczego

Gdy ta opcja jest włączona, programy HWASan i ASan automatycznie sprawdzają, czy w pamięci nie występują uszkodzenia w całym środowisku wykonawczym aplikacji.

W przypadku wykrycia błędu pamięci aplikacja ulega awarii i wyświetla błąd SIGBART (przerwanie sygnału), a potem wyświetla szczegółowy komunikat do logcat. Kopia wiadomości jest też zapisywana w pliku w folderze /data/tombstones.

Komunikat o błędzie wygląda mniej więcej tak:

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)

Wymagania wstępne

Zainstalowanie kompilacji HWASan dla systemu operacyjnego Android

Jeśli chcesz używać HWASan, wykonaj instrukcje konfiguracji podane w dokumentacji HWASan, aby zainstalować kompilację HWASan systemu operacyjnego Android na urządzenia Google Pixel.

W przypadku innych urządzeń skontaktuj się z producentem i uzyskaj kompilację systemu operacyjnego HWASan (o ile jest dostępna) lub skorzystaj z oprogramowania ASan.

Używanie udostępnionej biblioteki standardowej C++ w projekcie

Z powodu znanego problemu system ASan jest niezgodny z obsługą wyjątków C++ w przypadku użycia libc++_static. Ten problem nie występuje podczas korzystania z libc++_shared.

HWASan ma własną implementację operatorów new i delete, których nie można używać, jeśli biblioteka standardowa jest statycznie połączona z projektem.

Aby zmienić to ustawienie, zapoznaj się z sekcją Łączenie biblioteki standardowej C++ w tym dokumencie.

Włącz generowanie wskaźników klatek

HWASan i ASan używają szybkiego rozwijania opartego na wskaźnikach ramek do generowania informacji ze zrzutu stosu na potrzeby alokacji pamięci i zdarzeń transakcji. Oznacza to, że aby korzystać z tych funkcji, musisz włączyć generowanie wskaźników ramek w ustawieniach kompilatora C++. Oznacza to, że musisz wyłączyć optymalizację pomijania wskaźników klatek.

Aby zmienić to ustawienie, zapoznaj się z sekcją Włączanie generowania wskaźników klatek w tym dokumencie.

Konfigurowanie projektu Visual Studio pod kątem korzystania z HWASan lub ASan

Włączanie HWASan lub ASan

Aby włączyć HWASan lub ASan, otwórz Configuration Właściwości > General (Właściwości konfiguracji > Ogólne) na stronach usługi swojego projektu.

Menu właściwości Visual Studio Solution Explorer dla bieżącego projektu.

Rysunek 1. Opcja Właściwości projektu w oknie Eksploratora rozwiązań Visual Studio.

Okno właściwości projektu, w którym widać właściwości ogólne i wyróżnione ustawienia usługi Address Sanitizer.

Rysunek 2. Ustawienie Address Sanitizer (ASan) we właściwościach ogólnych właściwości projektu.

Aby włączyć HWASan w projekcie, zmień ustawienie Address Sanitizer (ASan) na Hardware ASan Enabled (fsanitize=hwaddress).

Aby włączyć ASan w projekcie, zmień ustawienie Address Sanitizer (ASan) na ASan Enabled (fsanitize=address).

Włączanie generowania wskaźników klatek

Generowanie wskaźników ramek jest kontrolowane za pomocą ustawienia kompilatora Pomiń wskaźnik ramki C/C++ na potrzeby kompilatora C/C++. Można je znaleźć w projekcie Strony usługi w sekcji Właściwości konfiguracji > C/C++ > Optymalizacja.

Okno właściwości projektu z wyróżnionymi właściwościami optymalizacji C/C++ i zaznaczonymi ustawieniami „Pomijaj wskaźniki ramki”.

Ilustracja 3. Gdzie znaleźć ustawienie Pomiń wskaźnik ramki

Jeśli korzystasz z HWASan lub ASan, dla ustawienia Pomiń wskaźnik ramki wybierz Nie (-fno-omit-frame-pointer).

Łączenie biblioteki standardowej C++ w trybie biblioteki udostępnionej

Ustawienie trybu łączenia dla biblioteki standardowej C++ znajdziesz na stronach usług swojego projektu, w obszarze Właściwości konfiguracji > Ogólne, w sekcji Wartości domyślne projektu.

Okno „Strony usługi projektu” z wyróżnioną kategorią „Ogólna” i zaznaczonym ustawieniem „Użycie STL”.

Rysunek 4. Gdzie znaleźć ustawienie trybu łączącego w bibliotece standardowej C++

Jeśli korzystasz z języka HWASan lub ASan, ustaw opcję Use of STL (Użycie STL) na Use of C++ Standard Library (.so) (Użyj bibliotek standardowych C++). Ta wartość łączy standardową bibliotekę C++ z projektem jako bibliotekę współdzieloną, która jest wymagana do poprawnego działania HWASan i ASan.

Tworzenie konfiguracji kompilacji na potrzeby użycia narzędzia Address Sanitizer

Jeśli wolisz korzystać przejściowo z HWASan lub ASan, nie musisz tworzyć nowej konfiguracji kompilacji na potrzeby tych użytkowników. Może tak być, jeśli projekt jest mały, badasz funkcję lub w reakcji na problem wykryty podczas testowania.

Jeśli jednak okaże się przydatna i będziesz regularnie z niej korzystać, rozważ utworzenie nowej konfiguracji kompilacji dla HWASan lub ASan, tak jak w przykładzie Teapot. Możesz to zrobić na przykład, jeśli regularnie korzystasz z narzędzia Address Sanitizer w ramach testów jednostkowych lub podczas nocnych testów dymu podczas gry.

Utworzenie oddzielnej konfiguracji kompilacji może być szczególnie przydatne, jeśli masz duży projekt, który zużywa dużą liczbę różnych bibliotek zewnętrznych, a które zwykle łączysz statyczne ze standardową biblioteką C++. Dedykowane konfiguracje kompilacji mogą pomóc w zapewnieniu dokładności ustawień projektu przez cały czas.

Aby utworzyć konfigurację kompilacji, na stronach usługi projektu kliknij przycisk Menedżer konfiguracji..., a następnie otwórz menu Aktywna konfiguracja rozwiązania. Następnie wybierz i utwórz nową konfigurację kompilacji o odpowiedniej nazwie (np. HWASan enabled).