Gỡ lỗi hỏng bộ nhớ bằng Address Sanitizer

Tài liệu này chỉ cho bạn cách bật các công cụ gỡ lỗi đặc biệt khi sử dụng AGDE. Các công cụ này có thể hữu ích với các lỗi ghi đè và lỗi hỏng bộ nhớ khó chẩn đoán.

HWAddress Sanitizer và Address Sanitizer

HWAddress Sanitizer (HWASan) và Address Sanitizer (ASan) là các công cụ gỡ lỗi hỏng bộ nhớ giúp gỡ các lỗi ghi đè và lỗi hỏng bộ nhớ sau đây:

  • Vùng đệm ngăn xếp bị tràn và trống
  • Vùng đệm của vùng nhớ khối xếp bị tràn và trống
  • Sử dụng ngăn xếp bên ngoài phạm vi của ngăn xếp
  • Lỗi giải phóng gấp đôi và lỗi giải phóng đối tượng không phải bộ nhớ khối xếp
  • Sử dụng ngăn xếp sau khi trả về (chỉ dành cho HWASan)

Bạn chỉ nên bật HWASan hoặc ASan khi đang gỡ lỗi sự cố hoặc đang ở chế độ kiểm thử tự động. Mặc dù những công cụ này hoạt động hiệu quả, nhưng chúng cũng sẽ có những điểm hạn chế riêng.

Hành vi trong thời gian chạy

Khi được bật, cả HWASan và ASan đều tự động kiểm tra lỗi hỏng bộ nhớ trong toàn bộ thời gian chạy của ứng dụng.

Nếu phát hiện thấy lỗi bộ nhớ, thì ứng dụng sẽ gặp phải lỗi SIGBART (huỷ bỏ tín hiệu) và in thông báo chi tiết tới logcat. Bản sao của thông báo cũng được ghi vào một tệp trong /data/tombstones.

Thông báo lỗi 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)

Điều kiện tiên quyết

Cài đặt bản dựng HWASan của Hệ điều hành Android

Để sử dụng HWASan, hãy làm theo Hướng dẫn thiết lập trong tài liệu về HWASan để cài đặt một bản dựng HWASan của Hệ điều hành Android cho thiết bị Google Pixel.

Đối với các thiết bị khác, hãy liên hệ với nhà sản xuất để lấy bản dựng HWASan của hệ điều hành (nếu có) hoặc sử dụng công cụ ASan chỉ dành cho phần mềm.

Dùng Thư viện chuẩn C++ dùng chung trong dự án của bạn

Do một vấn đề đã biết, ASan không tương thích với cách xử lý ngoại lệ C++ khi sử dụng libc++_static. Vấn đề này không thấy xuất hiện khi dùng libc++_shared.

HWASan có cách triển khai riêng đối với các toán tử newdelete. Các toán tử này không dùng được nếu thư viện chuẩn được liên kết tĩnh với dự án.

Để thay đổi chế độ cài đặt này, hãy xem phần Liên kết Thư viện chuẩn C++ trong tài liệu này.

Bật tính năng tạo con trỏ khung

HWASan và ASan sử dụng bộ tháo dỡ (unwinder) nhanh dựa trên con trỏ khung để tạo thông tin về dấu vết ngăn xếp cho các sự kiện phân bổ và giải phóng bộ nhớ. Điều này có nghĩa là bạn phải bật tính năng tạo con trỏ khung trong phần cài đặt trình biên dịch C++ để sử dụng các tính năng này. Tức là bạn cần tắt tính năng tối ưu hoá bỏ qua con trỏ khung.

Để thay đổi chế độ cài đặt này, hãy xem phần Bật tính năng tạo con trỏ khung trong tài liệu này.

Định cấu hình dự án Visual Studio để dùng HWASan hoặc ASan

Bật HWASan hoặc ASan

Để bật HWASan hoặc ASan, hãy tìm Configuration Properties > General (Thuộc tính cấu hình > Chung) trong Property Pages (Trang thuộc tính) cho dự án của bạn.

Trình đơn thuộc tính của Solution Explorer (Trình khám phá giải pháp) trong Visual Studio cho dự án hiện tại.

Hình 1: Tuỳ chọn Properties (Thuộc tính) trong cửa sổ Solution Explorer (Trình khám phá giải pháp) trong Visual Studio.

Hộp thoại Properties Page (Trang thuộc tính) của dự án với thuộc tính General (Chung) được hiển thị và các chế độ cài đặt Address Sanitizer được làm nổi bật.

Hình 2: Chế độ cài đặt của Address Sanitizer (ASan) trong thuộc tính chung của dự án.

Để bật HWASan cho dự án của bạn, hãy thay đổi chế độ cài đặt Address Sanitizer (ASan) thành Hardware ASan enabled (fsanitize=hwaddress) (Bật ASan cho phần cứng (fsanitize=hwaddress)).

Để bật ASan cho dự án của bạn, hãy thay đổi chế độ cài đặt Address Sanitizer (ASan) thành ASan Enabled (fsanitize=address) (Bật ASan (fsanitize=address)).

Bật tính năng tạo con trỏ khung

Tính năng tạo con trỏ khung do chế độ cài đặt Omit Frame Pointer (Bỏ qua con trỏ khung) của trình biên dịch C/C++ kiểm soát và có thể tìm thấy trong Property Pages (Trang thuộc tính) của dự án trong phần Configuration Properties > C/C++ > Optimization (Thuộc tính cấu hình > C/C++ > Tối ưu hoá).

Hộp thoại Properties Page (Trang thuộc tính) của dự án với thuộc tính C/C++ Optimization (Tối ưu hoá C/C++) được hiển thị và các chế độ cài đặt Omit Frame Pointer (Bỏ qua con trỏ khung) được làm nổi bật.

Hình 3: Nơi để tìm chế độ cài đặt Omit Frame Pointer (Bỏ qua con trỏ khung).

Khi sử dụng HWASan hoặc ASan, hãy đặt chế độ cài đặt Omit Frame Pointer (Bỏ qua con trỏ khung) thành No (-fno-omit-frame-pointer) (Không (-fno-omit-frame-pointer)).

Liên kết Thư viện chuẩn C++ ở chế độ thư viện chia sẻ

Bạn có thể tìm thấy chế độ liên kết cho Thư viện chuẩn C++ tại Property Pages (Trang thuộc tính) của dự án trong mục Configuration Properties > General (Thuộc tính cấu hình > Chung) trong phần Project Defaults (Giá trị mặc định của dự án).

Hộp thoại Properties Page (Trang thuộc tính) của dự án với danh mục General (Chung) được chọn và chế độ cài đặt Use of STL (Sử dụng STL) được làm nổi bật.

Hình 4: Nơi tìm chế độ cài đặt cho chế độ liên kết của Thư viện chuẩn C++.

Trong khi sử dụng HWASan hoặc ASan, hãy đặt Use STL (Sử dụng STL) thành Use C++ Standard Libraries (.so) (Sử dụng Thư viện chuẩn C++ (.so)). Giá trị này liên kết thư viện chuẩn C++ đến dự án của bạn dưới dạng một thư viện chia sẻ. Bạn bắt buộc phải có thư viện chia sẻ này để HWASan và ASan hoạt động đúng cách.

Tạo cấu hình bản dựng để sử dụng Address Sanitizer

Nếu chỉ muốn sử dụng HWASan hoặc ASan tạm thời, bạn có thể không muốn tạo một cấu hình bản dựng mới. Điều này có thể xảy ra nếu dự án của bạn có quy mô nhỏ, bạn đang khám phá tính năng hay đang đối phó với một vấn đề bạn phát hiện thấy trong quá trình kiểm thử.

Tuy nhiên, nếu thấy công cụ này hữu ích và định sử dụng thường xuyên, bạn có thể cân nhắc tạo một cấu hình bản dựng mới cho HWASan hoặc ASan như minh hoạ trong mẫu Teapot. Ví dụ: bạn có thể tạo cấu hình bản dựng mới nếu thường xuyên chạy Address Sanitizer trong quá trình kiểm thử đơn vị hoặc quá trình kiểm thử xác minh bản dựng qua đêm của trò chơi.

Việc tạo một cấu hình bản dựng riêng có thể đặc biệt hữu ích nếu dự án của bạn có quy mô lớn sử dụng số lượng lớn thư viện bên thứ ba. Đây cũng là nơi bạn thường liên kết tĩnh các thư viện đó với thư viện chuẩn C++. Cấu hình bản dựng riêng có thể giúp đảm bảo rằng chế độ cài đặt dự án của bạn luôn chính xác.

Để tạo cấu hình bản dựng, trên Property Pages (Trang thuộc tính) của dự án, hãy nhấp vào nút Configuration Manager… (Trình quản lý cấu hình…) rồi mở trình đơn thả xuống Active solution configuration (Cấu hình giải pháp đang hoạt động). Sau đó, chọn và tạo cấu hình bản dựng mới với tên phù hợp (ví dụ: HWASan enabled (Đã bật HWASan)).