Khi công cụ HWASan phát hiện lỗi bộ nhớ, quy trình sẽ bị chấm dứt bằng abort()
và báo cáo sẽ được in vào stderr và logcat. Giống như tất cả sự cố gốc trên Android, lỗi HWASan nằm trong /data/tombstones
.
Báo cáo mẫu
So với các sự cố gốc thông thường, HWASan mang thêm thông tin trong trường Abort message (Thông báo huỷ) ở gần đầu bia mộ. Dưới đây là một sự cố mẫu dựa trên vùng nhớ khối xếp. Đối với lỗi ngăn xếp, hãy xem ghi chú về các phần dành riêng cho ngăn xếp.
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 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 …]
Báo cáo này tương tự như báo cáo AddressSanitizer. Không giống như những lỗi đó, hầu hết lỗi HWASan đều là lỗi không khớp thẻ, tức là lỗi truy cập bộ nhớ trong đó thẻ con trỏ không khớp với thẻ bộ nhớ tương ứng. Có thể là một trong những trường hợp sau:
- Quyền truy cập ngoài giới hạn trên ngăn xếp hoặc vùng nhớ khối xếp
- Lỗi use-after-free trên vùng nhớ khối xếp
- Lỗi sử dụng sau khi trả về trên ngăn xếp
Phần
Sau đây là nội dung giải thích về 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
so vớiWRITE
) - Kích thước truy cập (số byte đã cố gắng truy cập)
- Số luồng của quyền 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 lỗi truy cập bộ nhớ không hợp lệ. Xem phần Biểu tượng hoá để biểu tượng hoá.
Nguyên nhân
Nguyên nhân có thể gây ra tình trạng truy cập không thành công. Nếu có nhiều đề xuất, các đề xuất đó sẽ được liệt kê theo thứ tự giảm dần về khả năng. Nằm trước thông tin chi tiết về nguyên nhân có thể xảy ra. HWASan có thể chẩn đoán các nguyên nhân sau:
- Sử dụng sau khi giải phóng
- Thẻ ngăn xếp không khớp, có thể là sử dụng ngăn xếp sau khi trả về, sử dụng ngăn xếp sau phạm vi hoặc nằm ngoài giới hạn
- Vùng đệm của vùng nhớ khối xếp bị tràn
- Tràn toàn cục
Thông tin về 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 | Sử dụng sau khi giải phóng | Sử dụng định dạng báo cáo này:<address> is located N bytes inside of M-byte region [<start>, <end>) freed by thread T0 here: |
Vùng đệm của vùng nhớ khối xếp bị tràn | Xin lưu ý rằng đây cũng có thể là một trường hợp tràn dưới.<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 | Báo cáo ngăn xếp không phân biệt giữa lỗi tràn hoặc lỗi thiếu dữ liệu và lỗi sử dụng sau khi trả về. Ngoài ra, để tìm cơ cấu phân bổ ngăn xếp là nguồn của lỗi, bạn cần thực hiện bước biểu tượng hoá ngoại tuyến. Xem phần Tìm hiểu về báo cáo ngăn xếp. | |
Không hợp lệ | Sử dụng sau khi giải phóng | Lỗi giải phóng hai lần. Nếu điều này xảy ra khi tắt quy trình, thì có thể là dấu hiệu của một lỗi 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ỉ | Một vùng nhớ trống ngẫu nhiên (không có bộ nhớ nào được phân bổ trước đó) hoặc một vùng nhớ trống đôi sau khi bộ nhớ được phân bổ bị loại bỏ khỏi vùng đệm trống của HWASan. | |
0x... là bộ nhớ bóng HWAsan | Một lỗi giải phóng bộ nhớ ngẫu nhiên, vì ứng dụng đang cố gắng giải phóng bộ nhớ nội bộ của HWASan. |
Dấu vết ngăn xếp giải phóng
Dấu vết ngăn xếp của nơi bộ nhớ được giải phóng. Chỉ xuất hiện đối với lỗi sử dụng sau khi giải phó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 của nơi bộ nhớ được phân bổ. Xem phần Biểu tượng hoá để biểu tượng hoá.
Thông tin gỡ lỗi nâng cao
Báo cáo HWASan cũng cung cấp một số thông tin gỡ lỗi nâng cao, bao gồm (theo thứ tự):
- Danh sách luồng trong quy trình
- Danh sách các luồng trong quy trình
- Giá trị của 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 báo lỗi gắn thẻ bộ nhớ
Bạn có thể sử dụng tệp báo lỗi bộ nhớ thẻ để tìm các lượt phân bổ bộ nhớ lân cận có cùng thẻ với thẻ con trỏ. Các thẻ này có thể trỏ đến một quyền truy cập ngoài giới hạn với độ dời lớn. Một thẻ tương ứng với 16 byte 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í dụ: sau đây là trường hợp tràn vùng đệm 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 ý rằng 6 × 16 = 96 byte của thẻ ad
ở bên trái khớp với thẻ con trỏ.
Nếu kích thước của một lượt 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ẽ được lưu trữ dưới dạng thẻ bộ nhớ và thẻ này được lưu trữ dưới dạng thẻ hạt ngắn. Trong ví dụ trước, ngay sau phần phân bổ được in đậm có gắn thẻ ad
, chúng ta có phần phân bổ 5 × 16 + 4 = 84 byte của thẻ 5c
.
Thẻ bộ nhớ rỗng (ví dụ: tags: ad/00 (ptr/mem)
) cho biết lỗi sử dụng ngăn xếp sau khi trả về.
Tệp kết xuất đăng ký
Tệp báo lỗi trong báo cáo HWASan tương ứng với lệnh đã thực hiện truy cập bộ nhớ không hợp lệ. Tiếp theo tệp báo lỗi này là một tệp báo lỗi đăng ký khác từ trình xử lý tín hiệu Android thông thường. Bỏ qua tệp báo lỗi thứ hai vì tệp này được lấy khi HWASan gọi abort()
và không liên quan đến lỗi.
Biểu tượng hoá
Để 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 lỗi sử dụng sau phạm vi), bạn cần thực hiện bước tượng trưng ngoại tuyến.
Thiết lập lần đầu: cài đặt llvm-symbolizer
Để biểu tượng hoá, hệ thống của bạn phải cài đặt và truy cập được llvm-symbolizer
từ $PATH
. Trên Debian, bạn có thể cài đặt bằng sudo apt install llvm
.
Tải 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 chưa bị loại bỏ chứa các ký hiệu. Vị trí của các tệp này phụ thuộc vào loại bản dựng:
- Đối với các bản dựng cục bộ, các tệp biểu tượng nằm trong
out/target/product/<product>/symbols/
. - Đối với các bản dựng AOSP (ví dụ: được cài đặt ROM qua Android Flash Tool), các bản dựng sẽ nằm trên Android CI. Trong Cấu phần phần mềm cho bản dựng, 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 kiểm tra tài liệu của tổ chức để được hỗ trợ 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) [...]
Để giúp bạn hiểu các lỗi ngăn xếp, HWASan theo dõi các khung ngăn xếp trước đây. HWASan không chuyển đổi các lỗi này thành nội dung mà con người có thể hiểu được trong báo cáo lỗi và yêu cầu thêm một bước biểu tượng hoá.
Vi phạm ODR
Một số lỗi sử dụng sau khi giải phóng do HWASan báo cáo có thể cho biết lỗi vi phạm Quy tắc định nghĩa một (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, có thể dẫn đến lỗi sử dụng sau khi giải phóng.
Sau khi biểu tượng hoá, các lỗi vi phạm ODR sẽ hiển thị lỗi sử dụng sau khi giải phóng với __cxa_finalize
, trên cả ngăn xếp truy cập không hợp lệ và ngăn xếp đã giải phóng tại đây. Ngăn xếp đã được phân bổ tại đây trước đó chứa __dl__ZN6soinfo17call_constructorsEv
và sẽ trỏ đến vị trí trong chương trình xác định biến ở trên ngăn xếp.
Bạn có thể vi phạm ODR nếu sử dụng thư viện tĩnh. Nếu một thư viện tĩnh xác định một toàn cục C++ được liên kết vào nhiều thư viện dùng chung hoặc tệp thực thi, thì nhiều định nghĩa của cùng một biểu tượng có thể tồn tại trong cùng một không gian địa chỉ, gây ra lỗi ODR.
Khắc phục sự cố
Phần này mô tả một số lỗi và cách khắc phục.
HWAddressSanitizer không thể mô tả địa chỉ chi tiết hơn
Đôi khi, HWASan có thể hết dung lượng cho thông tin về các lần phân bổ bộ nhớ trước đây. Trong trường hợp đó, báo cáo chỉ chứa một dấu vết ngăn xếp cho quyền truy cập bộ nhớ tức thì, 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 kích thước nhật ký HWASan. Bạn có thể thực hiện việc này trên toàn cục trong build/soong/cc/sanitize.go
(tìm hwasanGlobalOptions
) hoặc trong môi trường quy trình (thử adb shell echo $HWASAN_OPTIONS
để xem chế độ cài đặt hiện tại).
Lỗi này cũng có thể xảy ra nếu bộ nhớ được truy cập không được ánh xạ hoặc được phân bổ bởi trình phân bổ không nhận biết được HWASan. Trong trường hợp này, thẻ mem
được liệt kê trong tiêu đề sự cố thường là 00
. Nếu bạn có quyền truy cập vào tệp tombstone đầy đủ, bạn nên tham khảo tệp báo lỗi để tìm hiểu địa chỉ thuộc về mối liên kết nào (nếu có).
Lỗi lồng nhau 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 thời gian chạy HWASan. Gửi lỗi và cung cấp hướng dẫn cách tái hiện vấn đề (nếu có thể).