Đọc báo cáo lỗi

Lỗi là điều không thể tránh khỏi trong mọi loại hình phát triển và báo cáo lỗi là yếu tố quan trọng để xác định và giải quyết vấn đề. Tất cả các phiên bản Android đều hỗ trợ việc ghi lại báo cáo lỗi bằng Cầu gỡ lỗi Android (adb); Android phiên bản 4.2 trở lên hỗ trợ Tuỳ chọn cho nhà phát triển để ghi lại báo cáo lỗi và chia sẻ qua email, Drive, v.v.

Báo cáo lỗi Android chứa dữ liệu dumpsys, dumpstatelogcat ở định dạng văn bản (.txt), giúp bạn dễ dàng tìm kiếm nội dung cụ thể. Các phần sau đây trình bày chi tiết các thành phần của báo cáo lỗi, mô tả các vấn đề thường gặp và đưa ra các mẹo hữu ích cũng như các lệnh grep để tìm nhật ký liên quan đến những lỗi đó. Hầu hết các phần cũng có ví dụ về lệnh và kết quả grep và/hoặc kết quả dumpsys.

Logcat

Nhật ký logcat là một tệp kết xuất dựa trên chuỗi của tất cả thông tin logcat. Phần hệ thống được dành riêng cho khung và có lịch sử lâu đời hơn main (chứa mọi thứ khác). Mỗi dòng thường bắt đầu bằng timestamp UID PID TID log-level, mặc dù UID có thể không xuất hiện trong các phiên bản Android cũ.

Xem nhật ký sự kiện

Nhật ký này chứa các chuỗi biểu thị thông điệp nhật ký có định dạng nhị phân. Nhật ký này ít gây phiền toái hơn nhật ký logcat nhưng cũng khó đọc hơn một chút. Khi xem nhật ký sự kiện, bạn có thể tìm kiếm mã nhận dạng quy trình (PID) cụ thể trong phần này để xem một quy trình đã làm gì. Định dạng cơ bản là: timestamp PID TID log-level log-tag tag-values.

Các cấp độ nhật ký bao gồm:

  • V: chi tiết
  • D: gỡ lỗi
  • I: thông tin
  • W: cảnh báo
  • E: error

 

Để biết các thẻ nhật ký sự kiện hữu ích khác, hãy tham khảo /services/core/java/com/android/server/EventLogTags.logtags.

Lỗi ANR và bế tắc

Báo cáo lỗi có thể giúp bạn xác định nguyên nhân gây ra lỗi Ứng dụng không phản hồi (ANR) và các sự kiện bế tắc.

Xác định ứng dụng không phản hồi

Khi một ứng dụng không phản hồi trong một khoảng thời gian nhất định (thường là do luồng chính bị chặn hoặc bận), hệ thống sẽ dừng quy trình và kết xuất ngăn xếp vào /data/anr. Để tìm ra nguyên nhân gây ra lỗi ANR, hãy tìm am_anr trong nhật ký sự kiện nhị phân.

Bạn cũng có thể tìm kiếm ANR in trong nhật ký logcat. Nhật ký này chứa thêm thông tin về những gì đang sử dụng CPU tại thời điểm xảy ra lỗi ANR.

Tìm dấu vết ngăn xếp

Bạn thường có thể tìm thấy dấu vết ngăn xếp tương ứng với lỗi ANR. Đảm bảo dấu thời gian và PID trên dấu vết VM khớp với lỗi ANR mà bạn đang điều tra, sau đó kiểm tra luồng chính của quy trình. Lưu ý:

  • Luồng chính chỉ cho bạn biết luồng đang làm gì tại thời điểm xảy ra lỗi ANR, điều này có thể hoặc không tương ứng với nguyên nhân thực sự gây ra lỗi ANR. (Ngăn xếp trong báo cáo lỗi có thể không có vấn đề gì; có thể một thành phần khác đã bị kẹt trong một thời gian dài (nhưng không đủ lâu để gây ra lỗi ANR) trước khi được giải phóng.)
  • Có thể có nhiều bộ dấu vết ngăn xếp (VM TRACES JUST NOWVM TRACES AT LAST ANR). Đảm bảo rằng bạn đang xem đúng phần.

Tìm tình trạng tắc nghẽn

Tình trạng bế tắc thường xuất hiện lần đầu dưới dạng lỗi ANR vì các luồng bị kẹt. Nếu bế tắc xảy ra với máy chủ hệ thống, thì trình giám sát sẽ huỷ máy chủ đó, dẫn đến một mục nhập trong nhật ký tương tự như sau: WATCHDOG KILLING SYSTEM PROCESS. Theo quan điểm của người dùng, thiết bị sẽ khởi động lại, mặc dù về mặt kỹ thuật, đây là một lần khởi động lại thời gian chạy chứ không phải là một lần khởi động lại thực sự.

  • Trong quá trình khởi động lại thời gian chạy, máy chủ hệ thống sẽ ngừng hoạt động và được khởi động lại; người dùng sẽ thấy thiết bị quay lại ảnh động khởi động.
  • Trong quá trình khởi động lại, nhân đã gặp sự cố; người dùng thấy thiết bị quay lại biểu trưng khởi động của Google.

Để tìm ra các bế tắc, hãy kiểm tra các phần dấu vết VM để tìm một mẫu của luồng A đang chờ một thứ do luồng B giữ, đến lượt luồng B đang chờ một thứ do luồng A giữ.

Hoạt động

Hoạt động là một thành phần ứng dụng cung cấp màn hình mà người dùng tương tác để làm việc gì đó, chẳng hạn như quay số, chụp ảnh, gửi email, v.v. Theo góc độ báo cáo lỗi, hoạt động là một việc duy nhất, tập trung mà người dùng có thể làm, điều này khiến việc xác định vị trí hoạt động đang được tập trung trong quá trình gặp sự cố trở nên rất quan trọng. Các hoạt động (thông qua ActivityManager) chạy các quy trình, vì vậy, việc xác định vị trí của tất cả các quy trình dừng và bắt đầu cho một hoạt động nhất định cũng có thể hỗ trợ khắc phục sự cố.

Xem các hoạt động được tập trung

Để xem nhật ký các hoạt động được tập trung, hãy tìm am_focused_activity.

Xem số lượt bắt đầu quy trình

Để xem nhật ký về các lần khởi động quy trình, hãy tìm Start proc.

Xác định xem thiết bị có đang bị lỗi truy cập dữ liệu liên tục hay không

Để xác định xem thiết bị có đang thrashing hay không, hãy kiểm tra xem có sự gia tăng bất thường về hoạt động xung quanh am_proc_diedam_proc_start trong một khoảng thời gian ngắn hay không.

Bộ nhớ

Vì các thiết bị Android thường có bộ nhớ thực bị hạn chế, nên việc quản lý bộ nhớ truy cập ngẫu nhiên (RAM) là rất quan trọng. Báo cáo lỗi chứa một số chỉ báo về tình trạng bộ nhớ thấp cũng như một dumpstate cung cấp ảnh chụp nhanh bộ nhớ.

Xác định tình trạng bộ nhớ thấp

Bộ nhớ thấp có thể khiến hệ thống gặp sự cố khi đóng một số quy trình để giải phóng bộ nhớ nhưng vẫn tiếp tục khởi động các quy trình khác. Để xem bằng chứng xác thực về tình trạng thiếu bộ nhớ, hãy kiểm tra xem có nhiều mục am_proc_diedam_proc_start trong nhật ký sự kiện nhị phân hay không.

Bộ nhớ thấp cũng có thể làm chậm quá trình chuyển đổi tác vụ và cản trở các nỗ lực quay lại (vì tác vụ mà người dùng đang cố gắng quay lại đã bị huỷ). Nếu trình chạy bị tắt, trình chạy sẽ khởi động lại khi người dùng chạm vào nút trang chủ và nhật ký cho thấy trình chạy tải lại nội dung của trình chạy.

Xem các chỉ báo trong quá khứ

Mục am_low_memory trong nhật ký sự kiện nhị phân cho biết quy trình được lưu vào bộ nhớ đệm gần đây nhất đã bị huỷ. Sau đó, hệ thống bắt đầu ngừng các dịch vụ.

Xem chỉ báo về tình trạng truy cập dữ liệu quá mức

Các chỉ báo khác về tình trạng hệ thống bị tráo đổi (phân trang, thu hồi trực tiếp, v.v.) bao gồm kswapd, kworkermmcqd tiêu thụ các chu kỳ. (Xin lưu ý rằng báo cáo lỗi đang được thu thập có thể ảnh hưởng đến các chỉ báo về hiện tượng giật.)

Nhật ký ANR có thể cung cấp thông tin tổng quan nhanh tương tự về bộ nhớ.

Xem ảnh chụp nhanh kỷ niệm

Ảnh chụp nhanh bộ nhớ là một dumpstate liệt kê các quy trình Java và quy trình gốc đang chạy (để biết thông tin chi tiết, hãy tham khảo phần Xem mức phân bổ bộ nhớ tổng thể). Xin lưu ý rằng ảnh chụp nhanh chỉ cho biết trạng thái tại một thời điểm cụ thể; hệ thống có thể ở trạng thái tốt hơn (hoặc tệ hơn) trước khi chụp ảnh nhanh.

Truyền phát

Các ứng dụng tạo thông báo truyền tin để gửi sự kiện trong ứng dụng hiện tại hoặc đến một ứng dụng khác. Broadcast receiver đăng ký các thông báo cụ thể (thông qua bộ lọc), cho phép chúng vừa lắng nghe vừa phản hồi một thông báo phát. Báo cáo lỗi chứa thông tin về các thông báo truyền tin đã gửi và chưa gửi, cũng như một dumpsys của tất cả các bộ nhận đang lắng nghe một thông báo truyền tin cụ thể.

Xem các chương trình phát sóng trước đây

Thông báo phát sóng trước đây là những thông báo đã được gửi, được liệt kê theo thứ tự thời gian đảo ngược.

Phần tóm tắt là thông tin tổng quan về 300 thông báo phát trên nền trước gần đây nhất và 300 thông báo phát trên nền sau gần đây nhất.

Phần detail (chi tiết) chứa thông tin đầy đủ về 50 thông báo truyền tin ở nền trước và 50 thông báo truyền tin ở nền sau gần đây nhất, cũng như các receiver (trình nhận) cho mỗi thông báo truyền tin. Các thiết bị nhận có:

  • Mục BroadcastFilter được đăng ký trong thời gian chạy và chỉ được gửi đến các quy trình đang chạy.
  • Mục ResolveInfo được đăng ký thông qua các mục trong tệp kê khai. ActivityManager sẽ bắt đầu quy trình cho từng ResolveInfo nếu quy trình đó chưa chạy.

Xem các chương trình phát sóng đang diễn ra

Thông báo phát sóng đang hoạt động là những thông báo chưa được gửi. Số lượng lớn trong hàng đợi có nghĩa là hệ thống không thể gửi các thông báo truyền tin đủ nhanh để theo kịp.

Xem người nghe chương trình phát sóng

Để xem danh sách các receiver đang chờ nghe một thông báo truyền tin, hãy kiểm tra Receiver Resolver Table (Bảng phân giải receiver) trong dumpsys activity broadcasts. Ví dụ sau đây cho thấy tất cả các receiver đang nghe USER_PRESENT.

Theo dõi tranh chấp

Đôi khi, tính năng ghi nhật ký tranh chấp màn hình có thể cho biết tình trạng tranh chấp màn hình thực tế, nhưng thường cho biết hệ thống bị tải quá nhiều đến mức mọi thứ đều chậm lại. Bạn có thể thấy các sự kiện giám sát dài do ART ghi lại trong nhật ký hệ thống hoặc nhật ký sự kiện.

Trong nhật ký hệ thống:

10-01 18:12:44.343 29761 29914 W art     : Long monitor contention event with owner method=void android.database.sqlite.SQLiteClosable.acquireReference() from SQLiteClosable.java:52 waiters=0 for 3.914s

Trong nhật ký sự kiện:

10-01 18:12:44.364 29761 29914 I dvm_lock_sample: [com.google.android.youtube,0,pool-3-thread-9,3914,ScheduledTaskMaster.java,138,SQLiteClosable.java,52,100]

Biên dịch ở chế độ nền

Quá trình biên dịch có thể tốn kém và làm quá tải thiết bị.

Quá trình biên dịch có thể diễn ra ở chế độ nền khi các bản cập nhật của Cửa hàng Google Play đang tải xuống. Trong trường hợp này, thông báo từ ứng dụng Cửa hàng Google Play (finsky) và installd sẽ xuất hiện trước thông báo dex2oat.

Quá trình biên dịch cũng có thể diễn ra ở chế độ nền khi một ứng dụng đang tải một tệp dex chưa được biên dịch. Trong trường hợp này, bạn sẽ không thấy nhật ký finsky hoặc installd.

Kể chuyện

Việc thiết lập câu chuyện về một vấn đề (vấn đề bắt đầu như thế nào, điều gì đã xảy ra, hệ thống phản ứng như thế nào) đòi hỏi phải có một dòng thời gian vững chắc về các sự kiện. Bạn có thể sử dụng thông tin trong báo cáo lỗi để đồng bộ hoá dòng thời gian trên nhiều nhật ký và xác định dấu thời gian chính xác của báo cáo lỗi.

Đồng bộ hoá dòng thời gian

Báo cáo lỗi phản ánh nhiều dòng thời gian song song: nhật ký hệ thống, nhật ký sự kiện, nhật ký nhân và nhiều dòng thời gian chuyên biệt cho thông báo truyền tin, số liệu thống kê về pin, v.v. Rất tiếc là các dòng thời gian thường được báo cáo bằng nhiều cơ sở thời gian khác nhau.

Dấu thời gian của nhật ký hệ thống và nhật ký sự kiện nằm ở cùng múi giờ với người dùng (cũng như hầu hết các dấu thời gian khác). Ví dụ: khi người dùng nhấn nút trang chủ, nhật ký hệ thống sẽ báo cáo:

10-03 17:19:52.939  1963  2071 I ActivityManager: START u0 {act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10200000 cmp=com.google.android.googlequicksearchbox/com.google.android.launcher.GEL (has extras)} from uid 1000 on display 0

Đối với cùng một thao tác, nhật ký sự kiện sẽ báo cáo:

10-03 17:19:54.279  1963  2071 I am_focused_activity: [0,com.google.android.googlequicksearchbox/com.google.android.launcher.GEL]

Nhật ký kernel (dmesg) sử dụng cơ sở thời gian khác, gắn thẻ các mục nhật ký bằng số giây kể từ khi trình tải khởi động hoàn tất. Để đăng ký thang thời gian này vào các thang thời gian khác, hãy tìm kiếm thông báo suspend exit (tạm dừng thoát) và suspend entry (tạm dừng nhập):

<6>[201640.779997] PM: suspend exit 2015-10-03 19:11:06.646094058 UTC
…
<6>[201644.854315] PM: suspend entry 2015-10-03 19:11:10.720416452 UTC

Vì nhật ký nhân có thể không bao gồm thời gian trong khi ở trạng thái tạm ngưng, bạn nên đăng ký nhật ký theo từng phần giữa các thông báo nhập và thoát tạm ngưng. Ngoài ra, nhật ký kernel sử dụng múi giờ UTC và phải được điều chỉnh theo múi giờ của người dùng.

Xác định thời gian báo cáo lỗi

Để xác định thời điểm thực hiện báo cáo lỗi, trước tiên hãy kiểm tra nhật ký hệ thống (Logcat) để biết dumpstate: begin:

10-03 17:19:54.322 19398 19398 I dumpstate: begin

Tiếp theo, hãy kiểm tra dấu thời gian (dmesg) của thông báo Starting service 'bugreport' trong nhật ký hạt nhân:

<5>[207064.285315] init: Starting service 'bugreport'...

Hãy làm ngược lại để tương quan hai sự kiện, lưu ý đến những điểm cần lưu ý được đề cập trong phần Đồng bộ hoá dòng thời gian. Mặc dù có nhiều hoạt động diễn ra sau khi báo cáo lỗi được bắt đầu, nhưng hầu hết hoạt động đều không hữu ích vì hành động lấy báo cáo lỗi sẽ tải hệ thống một cách đáng kể.

Sức mạnh

Nhật ký sự kiện chứa trạng thái nguồn màn hình, trong đó 0 là màn hình tắt, 1 là màn hình bật và 2 là khi khoá màn hình hoàn tất.

Báo cáo lỗi cũng chứa số liệu thống kê về khoá đánh thức, một cơ chế mà nhà phát triển ứng dụng dùng để cho biết ứng dụng của họ cần giữ cho thiết bị luôn bật. (Để biết thông tin chi tiết về khoá chế độ thức, hãy tham khảo PowerManager.WakeLockLuôn bật CPU.)

Số liệu thống kê tổng hợp về thời lượng khoá chế độ thức chỉ theo dõi thời gian mà một khoá chế độ thức thực sự chịu trách nhiệm giữ cho thiết bị ở trạng thái thức và không bao gồm thời gian màn hình ở trạng thái bật. Ngoài ra, nếu nhiều khoá chế độ thức được giữ đồng thời, thì thời gian duy trì khoá chế độ thức sẽ được phân phối trên các khoá chế độ thức đó.

Để được trợ giúp thêm về việc trực quan hoá trạng thái nguồn điện, hãy sử dụng Battery Historian, một công cụ nguồn mở của Google để phân tích mức tiêu thụ pin bằng các tệp bugreport của Android.

Gói

Phần DUMP OF SERVICE package chứa các phiên bản ứng dụng (và thông tin hữu ích khác).

Quá trình

Báo cáo lỗi chứa một lượng lớn dữ liệu cho các quy trình, bao gồm cả thời gian bắt đầu và dừng, thời lượng thời gian chạy, các dịch vụ liên kết, điểm số oom_adj, v.v. Để biết thông tin chi tiết về cách Android quản lý các quy trình, hãy tham khảo phần Quy trình và luồng.

Xác định thời gian chạy quy trình

Mục procstats chứa số liệu thống kê đầy đủ về thời gian chạy của các quy trình và dịch vụ liên quan. Để xem bản tóm tắt nhanh, dễ đọc, hãy tìm AGGREGATED OVER để xem dữ liệu trong 3 hoặc 24 giờ qua, sau đó tìm Summary: để xem danh sách các quy trình, thời gian chạy của các quy trình đó ở nhiều mức độ ưu tiên và mức sử dụng RAM của các quy trình đó được định dạng là PSS tối thiểu-trung bình-tối đa/USS tối thiểu-trung bình-tối đa.

Lý do một quy trình đang chạy

Mục dumpsys activity processes liệt kê tất cả các quy trình hiện đang chạy theo thứ tự điểm oom_adj (Android cho biết tầm quan trọng của quy trình bằng cách chỉ định cho quy trình một giá trị oom_adj mà ActivityManager có thể cập nhật động). Đầu ra tương tự như đầu ra của ảnh chụp nhanh bộ nhớ nhưng có thêm thông tin về nguyên nhân khiến quy trình chạy. Trong ví dụ dưới đây, các mục được in đậm cho biết quy trình gms.persistent đang chạy ở mức độ ưu tiên vis (có thể thấy) vì quy trình hệ thống được liên kết với NetworkLocationService.

Bản quét

Hãy làm theo các bước sau để xác định những ứng dụng thực hiện quá nhiều lượt quét Bluetooth Low Energy (BLE):

  • Tìm thông điệp nhật ký cho BluetoothLeScanner:
    $ grep 'BluetoothLeScanner' ~/downloads/bugreport.txt
    07-28 15:55:19.090 24840 24851 D BluetoothLeScanner: onClientRegistered() - status=0 clientIf=5
    
  • Xác định PID trong thông báo nhật ký. Trong ví dụ này, "24840" và "24851" là PID (mã nhận dạng quy trình) và TID (mã nhận dạng luồng).
  • Tìm ứng dụng được liên kết với PID:
    PID #24840: ProcessRecord{4fe996a 24840:com.badapp/u0a105}
    

    Trong ví dụ này, tên gói là com.badapp.

  • Tìm tên gói trên Google Play để xác định ứng dụng chịu trách nhiệm: https://play.google.com/store/apps/details?id=com.badapp.

Lưu ý: Đối với các thiết bị chạy Android 7.0, hệ thống sẽ thu thập dữ liệu cho các hoạt động quét BLE và liên kết những hoạt động này với ứng dụng khởi tạo. Để biết thông tin chi tiết, hãy xem phần Quét Bluetooth và Năng lượng thấp (LE).