Hiểu báo cáo HWASan

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

So với các sự cố gốc thông thường, HWASan mang thêm thông tin trong trường “Thông báo hủy bỏ” ở gần đầu bia mộ. Xem sự cố dựa trên vùng nhớ khối mẫu bên dưới (đối với lỗi ngăn xếp, hãy xem ghi chú bên dưới để biết các phần dành riêng cho 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 rất giống với báo cáo addressSanitizer . Không giống như những lỗi đó, hầu hết tất cả các lỗi của HWASan đều là "thẻ không khớp", tức là truy cập bộ nhớ trong đó thẻ con trỏ không khớp với thẻ bộ nhớ tương ứng. Đây có thể là một trong

  • truy cập ngoài giới hạn trên ngăn xếp hoặc đống
  • sử dụng sau khi miễn phí trên heap
  • sử dụng sau khi trả về ngăn xếp

Phần

Dưới đây là phần 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ề việc truy cập bộ nhớ xấu, bao gồm:

  • Loại truy cập ("ĐỌC" so với " VIẾT")
  • Kích thước truy cập (có bao nhiêu byte đã được truy cập)
  • Số chủ đề của quyền truy cập
  • Thẻ con trỏ và thẻ nhớ (để 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 việc truy cập bộ nhớ xấu. Xem phần Ký hiệu hóa để tượng trưng.

Gây ra

Nguyên nhân tiềm ẩn cho việc truy cập xấu. Nếu có nhiều ứng cử viên, chúng sẽ được liệt kê theo thứ tự khả năng giảm dần. Đi 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:

  • sử dụng sau miễn phí
  • thẻ ngăn xếp không khớp: đây có thể là ngăn xếp sử dụng sau khi trả về/sử dụng sau phạm vi hoặc ngoài giới hạn
  • tràn bộ đệm
  • tràn toàn cầu

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 tùy theo loại lỗi.

Loại lỗi Gây ra Định dạng báo cáo
Thẻ không phù hợp sử dụng sau miễn phí
<address> is located N bytes inside of M-byte region [<start>, <end>)
  freed by thread T0 here:
tràn bộ đệm Lưu ý rằng đây cũng có thể là một dòng chảy ngầm.
<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/tràn và lỗi sử dụng sau khi trả lại. Ngoài ra, để tìm phân bổ ngăn xếp là nguồn gốc của lỗi, cần phải có bước ký hiệu ngoại tuyến. Xem phần Tìm hiểu báo cáo ngăn xếp bên dưới.
không hợp lệ sử dụng sau miễn phí Đây là một lỗi miễn phí gấp đôi. Nếu điều này xảy ra khi tắt quy trình, điều này có thể biểu thị sự 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ỉ Hoặc là trống tự nhiên (không có bộ nhớ chưa được phân bổ trước đó) hoặc trống gấp đôi sau khi bộ nhớ được phân bổ bị xóa khỏi bộ đệm trống của HWASan.
0x… là bộ nhớ bóng HWAsan. Đây chắc chắn là một điều hoàn toàn miễn phí vì ứng dụng đang cố gắng giải phóng bộ nhớ bên trong HWASan.

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

Dấu vết ngăn xếp nơi bộ nhớ được giải phóng. Chỉ hiện diện cho các lỗi không sử dụng sau hoặc không hợp lệ. Xem phần Ký hiệu để tượng trưng.

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

Dấu vết ngăn xếp nơi bộ nhớ được phân bổ. Xem phần Ký hiệu để tượng trưng.

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

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

  1. Danh sách các chủ đề trong quá trình
  2. Danh sách các chủ đề trong quá trình
  3. Giá trị của thẻ nhớ gần bộ nhớ bị lỗi
  4. Kết xuất các thanh ghi tại điểm truy cập bộ nhớ

Kết xuất thẻ nhớ

Kết xuất bộ nhớ thẻ có thể được sử dụng để tìm kiếm các phân bổ bộ nhớ lân cận có cùng thẻ với thẻ con trỏ. Những điều này có thể chỉ ra quyền truy cập ngoài giới hạn với mức chênh lệch 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ỉ. Kết xuất bộ nhớ thẻ có thể đưa ra gợi ý, ví dụ sau đây là lỗi tràn bộ đệm ở bên 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 của thẻ “quảng cáo” ở bên trái khớp với thẻ con trỏ).

Nếu kích thước của 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 dưới dạng thẻ bộ nhớ và thẻ sẽ được lưu dưới dạng thẻ hạt ngắn . Trong ví dụ trên, ngay sau quảng cáo được gắn thẻ phân bổ in đậm, chúng ta có phân bổ 5 × 16 + 4 = 84 byte của thẻ 5c.

Thẻ không có bộ nhớ (ví dụ: tags: ad/ 00 (ptr/mem) ) thường biểu thị lỗi sử dụng ngăn xếp sau khi trả về.

Đăng ký kết xuất

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

Biểu tượng hóa

Để 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 các lỗi sử dụng sau phạm vi), cần có bước ký hiệu ngoại tuyến.

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

Để biểu tượng, hệ thống của bạn phải cài đặt llvm-symbolizer và có thể truy cập từ $PATH. Trên Debian, bạn có thể cài đặt nó bằng sudo apt install llvm .

Lấy tập tin biểu tượng

Để ký hiệu hóa, chúng tôi yêu cầu các tệp nhị phân không bị tước bỏ có chứa các ký hiệu. Nơi có thể tìm thấy những thứ này tùy thuộc vào loại công trình:

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

Đối với các bản dựng AOSP (ví dụ: được flash từ Flashstation ), bạn có thể tìm thấy các bản dựng trên Android CI . Trong "Cấu phần phần mềm" của bản dựng, sẽ có tệp `${product}-symbols-${BUILDID}.zip`.

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

Tượng trưng

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

Hiểu 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 các 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)
  [...]
	

Để hiểu rõ cá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, HWASan không chuyển nội dung này thành nội dung dễ hiểu cho con người trong báo cáo lỗi và yêu cầu thêm một bước ký hiệu .

Vi phạm ODR

Một số lỗi use-after-free được HWASan báo cáo cũng có thể chỉ ra hành vi vi phạm Quy tắc một định nghĩa (ODR). 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ị hủy nhiều lần, điều này có thể dẫn đến lỗi use-after-free.

Sau khi ký hiệu hóa, các vi phạm ODR hiển thị trạng thái không sử dụng sau đó với __cxa_finalize , trên cả ngăn xếp truy cập không hợp lệ và ngăn xếp "được giải phóng ở đây". Ngăn xếp "được phân bổ trước đây ở đây" chứa __dl__ZN6soinfo17call_constructorsEv và phải trỏ đến vị trí trong chương trình của bạn xác định biến cao hơn trên ngăn xếp.

Một lý do khiến ODR có thể bị vi phạm là khi sử dụng thư viện tĩnh. Nếu một thư viện tĩnh xác định 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 ký hiệu có thể tồn tại trong cùng một không gian địa chỉ, điều này sẽ gây ra lỗi ODR.

Xử lý 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 để chứa thông tin về việc phân bổ bộ nhớ trong quá khứ. 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 bộ nhớ ngay lập tức, theo sau là ghi chú:

  HWAddressSanitizer can not describe address in more detail.

Trong một số trường hợp, điều này có thể được giải quyết bằng cách chạy thử nghiệm nhiều lần. Một tùy chọn khác là tăng kích thước lịch sử HWASan. Điều này có thể được thực hiện 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 (thử adb shell echo $HWASAN_OPTIONS để xem cài đặt hiện tại).

Điều 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 bộ cấp phát không phải của HWASan. 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 bạn có quyền truy cập vào bia mộ đầy đủ, có thể hữu ích khi tham khảo kết xuất bản đồ bộ nhớ để tìm ra địa chỉ đó thuộc về bản đồ nào (nếu có).

"lỗi lồng nhau trong cùng một chủ đề"

Đ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, vui lòng báo cáo lỗi và cung cấp hướng dẫn về cách tái tạo sự cố nếu có thể.