Tìm hiểu báo cáo HWASan

Khi công cụ HWASan phát hiện một lỗi bộ nhớ, quá trình này sẽ kết thúc bằng abort() và một báo cáo sẽ được in ra stderr và logcat. Giống như tất cả các sự cố gốc trên Android, lỗi HWASan có thể là được tìm thấy trong /data/tombstones.

So với các sự cố gốc thông thường, HWASan có thêm thông tin trong trường "Huỷ thông báo" ở gần phần trên cùng của bia mộ. Xem sự cố dựa trên vùng nhớ khối xếp mẫu ở bên dưới (để biết lỗi ngăn xếp, hãy xem ghi chú bên dưới để biết các phần cụ thể về ngăn xếp).

Báo cáo mẫu

*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
Build fingerprint: 'google/flame_hwasan/flame:Tiramisu/MASTER/7956676:userdebug/dev-keys'
Revision: 'DVT1.0'
ABI: 'arm64'
Timestamp: 2019-04-24 01:13:22+0000
pid: 11154, tid: 11154, name: sensors@1.0-ser  >>> /vendor/bin/hw/android.hardware.sensors@1.0-service <<<
signal 6 (SIGABRT), code -1 (SI_QUEUE), fault addr --------
Abort message: '

[...]

[0x00433ae20040,0x00433ae20060) is a small unallocated heap chunk; size: 32 offset: 5








[ … regular crash dump follows …]

Điều này tương tự như báo cáo AddressSanitizer. Không giống như các lỗi đó, hầu hết các lỗi HWASan đều là lỗi "tag-mismatch", tức là quyền truy cập vào bộ nhớ mà thẻ con trỏ thực hiện không khớp với thẻ bộ nhớ tương ứng. Đây có thể là một trong

  • quyền truy cập vượt quá giới hạn đối với ngăn xếp hoặc vùng nhớ khối xếp
  • sử dụng sau khi giải phóng trên bộ nhớ heap
  • sử dụng sau khi trả về trên ngăn xếp

Phần

Dưới đây là nội dung giải thích từng phần của báo cáo HWASan:

Lỗi truy cập

Chứa thông tin về quyền truy cập bộ nhớ không hợp lệ, bao gồm:

  • Loại quyền truy cập ("READ" và "ghi")
  • Kích thước truy cập (số byte cố gắng truy cập)
  • Số luồng truy cập
  • Con trỏ và thẻ bộ nhớ (dùng để gỡ lỗi nâng cao)

Truy cập dấu vết ngăn xếp

Dấu vết ngăn xếp của hoạt động truy cập bộ nhớ không hợp lệ. Xem phần Biểu tượng hoá để bằng biểu tượng.

Nguyên nhân

Nguyên nhân tiềm ẩn khiến quyền truy cập kém hiệu quả. Nếu có nhiều ứng viên, là được liệt kê theo thứ tự khả năng giảm dần. Đứng trước thông tin chi tiết về nguyên nhân tiềm ẩn. HWASan có thể chẩn đoán các nguyên nhân sau:

  • không cần dùng đến
  • stack tag-mismatch: đây có thể là ngăn xếp use-after-return / use after-scope hoặc vượt quá giới hạn
  • heap-buffer-overflow cho vùng nhớ khối xếp
  • tràn toàn bộ

Thông tin bộ nhớ

Mô tả những gì HWASan biết về bộ nhớ đang được truy cập và có thể khác nhau dựa trên loại lỗi.

Loại lỗi Nguyên nhân Định dạng báo cáo
thẻ-không khớp không cần dùng đến
<address> is located N bytes inside of M-byte region [<start>, <end>)
  freed by thread T0 here:
heap-buffer-overflow cho vùng nhớ khối xếp Lưu ý rằng đây cũng có thể là luồng dưới mức.
<address> is located N bytes to the right of M-byte region [<start>, <end>)
  allocated here:
thẻ ngăn xếp không khớp Các báo cáo ngăn xếp không phân biệt giữa tràn/dưới luồng và lỗi use-after-return (sử dụng sau khi trả về). Trong để tìm hoạt động phân bổ ngăn xếp là nguyên nhân gây ra lỗi, CANNOT TRANSLATE biểu tượng hoá là bước bắt buộc. Hãy xem bài viết Tìm hiểu về báo cáo ngăn xếp phần dưới đây.
không có giá trị hợp lệ không cần dùng đến Đây là lỗi không tính phí hai lần. Nếu điều này xảy ra khi quá trình ngừng hoạt động, thì đó có thể là dấu hiệu Vi phạm ODR.
<address> is located N bytes inside of M-byte region [<start>, <end>)
  freed by thread T0 here:
không thể mô tả địa chỉ Có thể là tự do (hết bộ nhớ chưa được phân bổ trước đây), hoặc miễn phí hai lần sau khi bộ nhớ được phân bổ bị loại khỏi bộ đệm trống của HWASan.
0x... là bộ nhớ bóng HWAsan. Đây chắc chắn là một ứng dụng tự do, vì ứng dụng đã cố gắng giải phóng bộ nhớ nội bộ sang HWASan.

Dấu vết ngăn xếp giao dịch

Dấu vết ngăn xếp về vị trí bộ nhớ được giải phóng. Chỉ hiển thị để sử dụng sau khi không sử dụng hoặc lỗi không hợp lệ. Xem phần Biểu tượng hoá để biểu tượng hoá.

Dấu vết ngăn xếp phân bổ

Dấu vết ngăn xếp về nơi bộ nhớ được phân bổ. Xem phần Biểu tượng hoá để biểu tượng hoá.

Gỡ lỗi nâng cao Thông tin

Báo cáo HWASan cũng nêu bật một số thông tin gỡ lỗi nâng cao, bao gồm (theo thứ tự):

  1. Danh sách các luồng trong quy trình
  2. Danh sách các luồng trong quy trình
  3. Giá trị của các thẻ bộ nhớ gần bộ nhớ bị lỗi
  4. Tệp kết xuất của các thanh ghi tại thời điểm truy cập bộ nhớ

Tệp kết xuất thẻ nhớ

Bạn có thể dùng tệp kết xuất bộ nhớ thẻ để tìm các lượt phân bổ bộ nhớ lân cận bằng cùng một thẻ với tư cách là con trỏ . Các URL này có thể cho thấy quyền truy cập vượt quá giới hạn với mức chênh lệch lớn. Một thẻ tương ứng với 16 byte của bộ nhớ; thẻ con trỏ là 8 bit trên cùng của địa chỉ. Tệp kết xuất bộ nhớ thẻ có thể đưa ra gợi ý, với ví dụ sau đây là một vùng đệm bị tràn sang phải:

tags: ad/5c (ptr/mem)
[...]
Memory tags around the buggy address (one tag corresponds to 16 bytes):
  0x006f33ae1ff0: 0e  0e  0e  57  20  20  20  20  20  2e  5e  5e  5e  5e  5e  b5
=>0x006f33ae2000: f6  f6  f6  f6  f6  4c  ad  ad  ad  ad  ad  ad [5c] 5c  5c  5c
  0x006f33ae2010: 5c  04  2e  2e  2e  2e  2e  2f  66  66  66  66  66  80  6a  6a
Tags for short granules around the buggy address (one tag corresponds to 16 bytes):
  0x006f33ae1ff0: ab  52  eb  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..
=>0x006f33ae2000: ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  .. [..] ..  ..  ..
  0x006f33ae2010: ..  5c  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..
(lưu ý chạy 6 × 16 = 96 byte thẻ "ad" ở bên trái khớp với thẻ con trỏ).

Nếu quy mô của một mức phân bổ không phải là bội số của 16, thì phần còn lại của kích thước sẽ là đã lưu trữ với tư cách là thẻ bộ nhớ và thẻ này sẽ được lưu trữ dưới dạng thẻ thẻ granule. Trong ví dụ trên, ngay sau khi phân bổ in đậm được gắn thẻ quảng cáo, chúng tôi CANNOT TRANSLATE × 16 + 4 = 84 byte cấp phát của thẻ 5c.

Thẻ bộ nhớ trống (ví dụ: tags: ad/00 (ptr/mem)) thường cho biết lỗi stack-use-after-return.

Tệp kết xuất đăng ký

Tệp kết xuất thanh ghi trong báo cáo HWASan tương ứng với lệnh thực hiện không hợp lệ bộ nhớ truy cập. Theo sau là một tệp kết xuất đăng ký khác từ trình xử lý tín hiệu Android thông thường – bỏ qua đường dẫn thứ hai được thực hiện khi HWASan gọi là abort() và không liên quan đến lỗi.

Biểu tượng

Để lấy tên hàm và số dòng trong dấu vết ngăn xếp (và lấy tên biến cho phạm vi sử dụng sau lỗi), thì cần phải thực hiện một bước thay thế bằng biểu tượng ngoại tuyến.

Thiết lập lần đầu tiên: cài đặt llvm-symbolizer

Để thay thế bằng biểu tượng, hệ thống của bạn phải cài đặt trình biểu tượng llvm và có thể truy cập từ $PATH. Trên Debian, bạn có thể bằng cách sử dụng sudo apt install llvm.

Lấy tệp biểu tượng

Để biểu tượng hoá, chúng tôi yêu cầu các tệp nhị phân không cắt có chứa biểu tượng. Vị trí có thể tìm thấy các thông tin này phụ thuộc vào về loại bản dựng:

Đối với bản dựng cục bộ, bạn có thể tìm thấy tệp biểu tượng trong out/target/product/<product>/symbols/.

Đối với các bản dựng AOSP (Dự án nguồn mở Android) (ví dụ: cài đặt ROM từ Flashstation), bản dựng trên Android CI. Trong phần "Cấu phần phần mềm" cho bản dựng, sẽ có một tệp ${PRODUCT}-symbols-${BUILDID}.zip.

Đối với các bản dựng nội bộ của tổ chức, hãy xem tài liệu của tổ chức để được trợ giúp lấy tệp biểu tượng.

Biểu tượng hoá

hwasan_symbolize –-symbols <DECOMPRESSED_DIR>/out/target/product/*/symbols < crash

Tìm hiểu về báo cáo ngăn xếp

Đối với các lỗi xảy ra với biến ngăn xếp, báo cáo HWASan sẽ chứa thông tin chi tiết như sau:

Cause: stack tag-mismatch
Address 0x007d4d251e80 is located in stack of thread T64
Thread: T64 0x0074000b2000 stack: [0x007d4d14c000,0x007d4d255cb0) sz: 1088688 tls: [0x007d4d255fc0,0x007d4d259000)
Previously allocated frames:
  record_addr:0x7df7300c98 record:0x51ef007df3f70fb0  (/apex/com.android.art/lib64/libart.so+0x570fb0)
  record_addr:0x7df7300c90 record:0x5200007df3cdab74  (/apex/com.android.art/lib64/libart.so+0x2dab74)
  [...]

Để cho phép hiểu được lỗi ngăn xếp, HWASan theo dõi các khung ngăn xếp đã xảy ra trong quá khứ. Hiện tại, trong báo cáo lỗi, HWASan không biến đổi thông tin này thành nội dung mà con người có thể hiểu được, và yêu cầu thêm một bước thay thế bằng biểu tượng.

Lỗi vi phạm ODR

Một số lỗi use-after-free do HWASan báo cáo cũng có thể chỉ ra lỗi vi phạm Quy tắc một định nghĩa (ODR). Lỗi vi phạm ODR xảy ra khi cùng một biến được xác định nhiều lần trong cùng một chương trình. Điều này cũng có nghĩa là biến đó bị huỷ nhiều lần, dẫn đến việc lỗi use-after-free.

Sau khi thay thế bằng biểu tượng, lỗi vi phạm ODR sẽ cho thấy trạng thái "không sử dụng" với __cxa_finalize, trên cả ngăn xếp truy cập không hợp lệ và "được giải phóng ở đây" ngăn xếp. Số liệu "được phân bổ trước đó" đây" ngăn xếp chứa __dl__ZN6soinfo17call_constructorsEv và nên trỏ đến vị trí trong chương trình giúp xác định biến cao hơn trong ngăn xếp.

Một lý do khiến ODR có thể bị vi phạm là khi bạn sử dụng thư viện tĩnh. Nếu một thư viện tĩnh định nghĩa một C++ toàn cục được liên kết với nhiều thư viện dùng chung hoặc tệp thực thi, nhiều định nghĩa của cùng một biểu tượng có thể sẽ tồn tại ở cùng một địa chỉ và sẽ gây ra lỗi ODR.

Khắc phục sự cố

HWAddressSanitizer không thể mô tả địa chỉ chi tiết hơn

Đôi khi, HWASan có thể hết dung lượng để lấy thông tin về các lượt phân bổ bộ nhớ trước đây. Trong trường hợp đó, báo cáo sẽ chỉ chứa một dấu vết ngăn xếp để truy cập ngay vào bộ nhớ, theo sau là một ghi chú:

  HWAddressSanitizer can not describe address in more detail.

Trong một số trường hợp, bạn có thể giải quyết vấn đề này bằng cách chạy kiểm thử nhiều lần. Một cách khác là tăng HWASan kích thước lịch sử. Bạn có thể thực hiện việc này trên toàn cầu trong build/soong/cc/sanitize.go (tìm hwasanGlobalOptions) hoặc trong môi trường quy trình của bạn (hãy thử adb shell echo $HWASAN_OPTIONS để xem chế độ cài đặt hiện tại).

Điều này cũng có thể xảy ra nếu bộ nhớ đã truy cập không được ánh xạ hoặc được phân bổ bởi một thiết bị không nhận biết được HWASan trình phân bổ. Trong trường hợp này, thẻ mem được liệt kê trong tiêu đề sự cố thường sẽ là 00 Nếu có quyền truy cập vào toàn bộ tombstone, bạn nên tham khảo bộ nhớ kết xuất ánh xạ để tìm hiểu xem địa chỉ thuộc về ánh xạ nào (nếu có).

Lỗi được lồng trong cùng một luồng

Điều này có nghĩa là đã xảy ra lỗi khi tạo báo cáo sự cố HWASan. Điều này thường là do lỗi trong Khi dùng HWASan, vui lòng báo cáo lỗi và cung cấp hướng dẫn về cách tái hiện vấn đề nếu có thể.