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: '==9569==ERROR: HWAddressSanitizer: tag-mismatch on address 0x00433ae20045 at pc 0x00623ae2a9cc READ of size 1 at 0x00433ae20045 tags: 5b/83 (ptr/mem) in thread T0 #0 0x7240450c68 (/system/lib64/vndk-sp-R/libcutils.so+0x8c68) #1 0x723dffd490 (/vendor/lib64/sensors.ssc.so+0x34490) #2 0x723e0126e0 (/vendor/lib64/sensors.ssc.so+0x496e0) [...] [0x00433ae20040,0x00433ae20060) is a small unallocated heap chunk; size: 32 offset: 5 Cause: use-after-free 0x00433ae20045 is located 5 bytes inside of 10-byte region [0x00433ae20040,0x00433ae2004a) freed by thread T0 here: #0 0x72404d1b18 (/system/lib64/libclang_rt.hwasan-aarch64-android.so+0x10b18) #1 0x723af23040 (/vendor/lib64/libgralloccore.so+0x5040) #2 0x723af23fa4 (/vendor/lib64/libgralloccore.so+0x5fa4) [...] previously allocated here: #0 0x72404ce554 (/system/lib64/libclang_rt.hwasan-aarch64-android.so+0xd554) #1 0x7240115654 (/apex/com.android.runtime/lib64/bionic/libc.so+0x43654) #2 0x7240450ac8 (/system/lib64/vndk-sp-R/libcutils.so+0x8ac8) [...] hwasan_dev_note_heap_rb_distance: 1 1023 hwasan_dev_note_num_matching_addrs: 0 hwasan_dev_note_num_matching_addrs_4b: 0 Thread: T0 0x006a00002000 stack: [0x007fc1064000,0x007fc1864000) sz: 8388608 tls: [0x00737702ffc0,0x007377033000) Memory tags around the buggy address (one tag corresponds to 16 bytes): 0x006f33ae1f80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1f90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1fa0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =>0x006f33ae2000: 08 00 08 00 [83] 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Tags for short granules around the buggy address (one tag corresponds to 16 bytes): 0x006f33ae1ff0: .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. =>0x006f33ae2000: 72 .. d0 .. [..] .. .. .. .. .. .. .. .. .. .. .. 0x006f33ae2010: .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. See https://clang.llvm.org/docs/HardwareAssistedAddressSanitizerDesign.html#short-granules for a description of short granule tags Registers where the failure occurred (pc 0x00623ae2a9cc): x0 0000007fc18623ec x1 5b0000433ae20045 x2 0000000000000013 x3 ffffffffffffffff x4 ffffffffffffffff x5 0000007fc1861da3 x6 6f7420676e696f47 x7 45522061206f6420 x8 0000000000000000 x9 0200006b00000000 x10 00000007fc18623f x11 5b0000433ae20040 x12 6f64206f7420676e x13 0a44414552206120 x14 0000000000000010 x15 ffffffffffffffff x16 000000737169ac94 x17 0000000000000007 x18 0000007377bd8000 x19 0000007fc1862498 x20 0200006b00000000 x21 0000007fc18624a8 x22 0000000000000001 x23 0000000000000000 x24 0000000000000000 x25 0000000000000000 x26 0000000000000000 x27 0000000000000000 x28 0000000000000000 x29 0000007fc1862410 x30 000000623ae2a9d0 sp 0000007fc18623d0 SUMMARY: HWAddressSanitizer: tag-mismatch (/system/lib64/vndk-sp-R/libcutils.so+0x8c68) [ … 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ự):
- Danh sách các luồng trong quy trình
- Danh sách các luồng trong quy trình
- Giá trị của các thẻ bộ nhớ gần bộ nhớ bị lỗi
- 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ể.