Google cam kết thúc đẩy công bằng chủng tộc cho Cộng đồng người da đen. Xem cách thực hiện.

Chẩn đoán sự cố gốc

Các phần sau bao gồm các loại va chạm bản địa phổ biến, phân tích bãi chứa mẫu và thảo luận về các bia mộ. Mỗi loại tai nạn bao gồm ví dụ debuggerd đầu ra bằng chứng quan trọng đánh dấu để giúp bạn phân biệt các loại cụ thể của vụ tai nạn.

Huỷ bỏ

Việc hủy bỏ là thú vị bởi vì chúng có chủ ý. Có rất nhiều cách khác nhau để hủy bỏ (kể cả kêu gọi abort(3) , không một assert(3) , sử dụng một trong những loại khai thác gỗ gây tử vong Android cụ thể), nhưng tất cả liên quan đến gọi abort . Một cuộc gọi đến abort tín hiệu thread gọi với SIGABRT, do đó, một hiển thị khung "hủy bỏ" trong libc.so cộng SIGABRT là những điều cần tìm kiếm trong các debuggerd đầu ra để nhận ra trường hợp này.

Có thể có một dòng "thông báo hủy bỏ" rõ ràng. Bạn cũng nên tìm trong các logcat đầu ra để xem những gì chủ đề này đăng nhập trước khi cố tình giết chết bản thân, bởi vì không giống như assert(3) hoặc cấp độ cao Thiết bị khai thác gỗ gây tử vong, abort(3) không chấp nhận một tin nhắn.

Phiên bản hiện tại của Android inline các tgkill(2) gọi hệ thống, do đó ngăn xếp của họ là dễ nhất để đọc, với lời kêu gọi hủy bỏ (3) ở trên cùng:

pid: 4637, tid: 4637, name: crasher  >>> crasher <<<
signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------
Abort message: 'some_file.c:123: some_function: assertion "false" failed'
    r0  00000000  r1  0000121d  r2  00000006  r3  00000008
    r4  0000121d  r5  0000121d  r6  ffb44a1c  r7  0000010c
    r8  00000000  r9  00000000  r10 00000000  r11 00000000
    ip  ffb44c20  sp  ffb44a08  lr  eace2b0b  pc  eace2b16
backtrace:
    #00 pc 0001cb16  /system/lib/libc.so (abort+57)
    #01 pc 0001cd8f  /system/lib/libc.so (__assert2+22)
    #02 pc 00001531  /system/bin/crasher (do_action+764)
    #03 pc 00002301  /system/bin/crasher (main+68)
    #04 pc 0008a809  /system/lib/libc.so (__libc_init+48)
    #05 pc 00001097  /system/bin/crasher (_start_main+38)

Các phiên bản Android cũ hơn tuân theo một đường dẫn phức tạp giữa lệnh gọi hủy bỏ ban đầu (khung 4 ở đây) và việc gửi tín hiệu thực tế (khung 0 ở đây). Điều này đặc biệt đúng trên 32-bit ARM, mà thêm __libc_android_abort (khung 3 ở đây) để tự của các nền tảng khác raise / pthread_kill / tgkill :

pid: 1656, tid: 1656, name: crasher  >>> crasher <<<
signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------
Abort message: 'some_file.c:123: some_function: assertion "false" failed'
    r0 00000000  r1 00000678  r2 00000006  r3 f70b6dc8
    r4 f70b6dd0  r5 f70b6d80  r6 00000002  r7 0000010c
    r8 ffffffed  r9 00000000  sl 00000000  fp ff96ae1c
    ip 00000006  sp ff96ad18  lr f700ced5  pc f700dc98  cpsr 400b0010
backtrace:
    #00 pc 00042c98  /system/lib/libc.so (tgkill+12)
    #01 pc 00041ed1  /system/lib/libc.so (pthread_kill+32)
    #02 pc 0001bb87  /system/lib/libc.so (raise+10)
    #03 pc 00018cad  /system/lib/libc.so (__libc_android_abort+34)
    #04 pc 000168e8  /system/lib/libc.so (abort+4)
    #05 pc 0001a78f  /system/lib/libc.so (__libc_fatal+16)
    #06 pc 00018d35  /system/lib/libc.so (__assert2+20)
    #07 pc 00000f21  /system/xbin/crasher
    #08 pc 00016795  /system/lib/libc.so (__libc_init+44)
    #09 pc 00000abc  /system/xbin/crasher

Bạn có thể tái tạo một thể hiện của loại tai nạn sử dụng crasher abort .

Tham khảo con trỏ rỗng thuần túy

Đây là sự cố gốc cổ điển và mặc dù nó chỉ là một trường hợp đặc biệt của loại sự cố tiếp theo, nhưng nó đáng được đề cập riêng vì nó thường đòi hỏi ít suy nghĩ nhất.

Trong ví dụ dưới đây, mặc dù chức năng đâm là trong libc.so , bởi vì các chức năng chuỗi chỉ hoạt động trên các con trỏ họ đang đưa ra, bạn có thể suy ra rằng strlen(3) được gọi với một con trỏ null; và sự cố này sẽ được chuyển thẳng đến tác giả của mã gọi điện. Trong trường hợp này, khung # 01 là người gọi xấu.

pid: 25326, tid: 25326, name: crasher  >>> crasher <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0
    r0 00000000  r1 00000000  r2 00004c00  r3 00000000
    r4 ab088071  r5 fff92b34  r6 00000002  r7 fff92b40
    r8 00000000  r9 00000000  sl 00000000  fp fff92b2c
    ip ab08cfc4  sp fff92a08  lr ab087a93  pc efb78988  cpsr 600d0030

backtrace:
    #00 pc 00019988  /system/lib/libc.so (strlen+71)
    #01 pc 00001a8f  /system/xbin/crasher (strlen_null+22)
    #02 pc 000017cd  /system/xbin/crasher (do_action+948)
    #03 pc 000020d5  /system/xbin/crasher (main+100)
    #04 pc 000177a1  /system/lib/libc.so (__libc_init+48)
    #05 pc 000010e4  /system/xbin/crasher (_start+96)

Bạn có thể tái tạo một thể hiện của loại tai nạn sử dụng crasher strlen-NULL .

Tham khảo con trỏ rỗng địa chỉ thấp

Trong nhiều trường hợp, địa chỉ lỗi sẽ không phải là 0 mà là một số thấp khác. Đặc biệt, địa chỉ có hai hoặc ba chữ số rất phổ biến, trong khi địa chỉ sáu chữ số gần như chắc chắn không phải là tham chiếu con trỏ rỗng — điều đó sẽ yêu cầu bù 1MiB. Điều này thường xảy ra khi bạn có mã tham chiếu đến một con trỏ null như thể nó là một cấu trúc hợp lệ. Chức năng phổ biến là fprintf(3) (hoặc bất kỳ chức năng khác tham gia một FILE *) và readdir(3) , bởi vì mã thường thất bại trong việc kiểm tra xem fopen(3) hoặc opendir(3) gọi thực sự thành công đầu tiên.

Dưới đây là một ví dụ về readdir :

pid: 25405, tid: 25405, name: crasher  >>> crasher <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xc
    r0 0000000c  r1 00000000  r2 00000000  r3 3d5f0000
    r4 00000000  r5 0000000c  r6 00000002  r7 ff8618f0
    r8 00000000  r9 00000000  sl 00000000  fp ff8618dc
    ip edaa6834  sp ff8617a8  lr eda34a1f  pc eda618f6  cpsr 600d0030

backtrace:
    #00 pc 000478f6  /system/lib/libc.so (pthread_mutex_lock+1)
    #01 pc 0001aa1b  /system/lib/libc.so (readdir+10)
    #02 pc 00001b35  /system/xbin/crasher (readdir_null+20)
    #03 pc 00001815  /system/xbin/crasher (do_action+976)
    #04 pc 000021e5  /system/xbin/crasher (main+100)
    #05 pc 000177a1  /system/lib/libc.so (__libc_init+48)
    #06 pc 00001110  /system/xbin/crasher (_start+96)

Đây là nguyên nhân trực tiếp của vụ tai nạn là pthread_mutex_lock(3) đã cố gắng để địa chỉ truy cập 0xc (khung 0). Nhưng điều đầu tiên pthread_mutex_lock làm là dereference các state yếu tố của pthread_mutex_t* nó đã được đưa ra. Nếu bạn nhìn vào các nguồn, bạn có thể thấy yếu tố đó là tại offset 0 trong cấu trúc, trong đó nói với bạn rằng pthread_mutex_lock đã được đưa con trỏ 0xc không hợp lệ. Từ khung 1, bạn có thể thấy rằng nó đã được đưa ra rằng con trỏ bởi readdir , được chiết xuất các mutex_ trường từ DIR* nó nhất định. Nhìn vào cấu trúc đó, bạn có thể thấy rằng mutex_ là bù đắp sizeof(int) + sizeof(size_t) + sizeof(dirent*) vào struct DIR , mà trên một thiết bị 32-bit là 4 + 4 + 4 = 12 = 0xc, do đó, bạn tìm thấy lỗi: readdir đã được thông qua một con trỏ null bởi người gọi. Tại thời điểm này bạn có thể dán chồng vào công cụ ngăn xếp để tìm ra nơi ở logcat điều này xảy ra.

  struct DIR {
    int fd_;
    size_t available_bytes_;
    dirent* next_;
    pthread_mutex_t mutex_;
    dirent buff_[15];
    long current_pos_;
  };

Trong hầu hết các trường hợp, bạn thực sự có thể bỏ qua phân tích này. Một địa chỉ lỗi đủ thấp thường có nghĩa là bạn chỉ có thể bỏ qua bất kỳ libc.so khung trong ngăn xếp và trực tiếp cáo buộc mã gọi. Nhưng không phải lúc nào cũng vậy, và đây là cách bạn trình bày một trường hợp hấp dẫn.

Bạn có thể mô phỏng các trường hợp của loại tai nạn sử dụng crasher fprintf-NULL hoặc crasher readdir-NULL .

FORTIFY thất bại

Lỗi FORTIFY là một trường hợp hủy bỏ đặc biệt xảy ra khi thư viện C phát hiện ra sự cố có thể dẫn đến lỗ hổng bảo mật. Nhiều chức năng thư viện C được tăng cường; họ có thêm một đối số để cho họ biết bộ đệm thực sự lớn như thế nào và kiểm tra lúc chạy xem thao tác bạn đang cố gắng thực hiện có thực sự phù hợp hay không. Dưới đây là một ví dụ nơi mã cố gắng read(fd, buf, 32) vào một bộ đệm đó là thực sự chỉ dài 10 byte ...

pid: 25579, tid: 25579, name: crasher  >>> crasher <<<
signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------
Abort message: 'FORTIFY: read: prevented 32-byte write into 10-byte buffer'
    r0 00000000  r1 000063eb  r2 00000006  r3 00000008
    r4 ff96f350  r5 000063eb  r6 000063eb  r7 0000010c
    r8 00000000  r9 00000000  sl 00000000  fp ff96f49c
    ip 00000000  sp ff96f340  lr ee83ece3  pc ee86ef0c  cpsr 000d0010

backtrace:
    #00 pc 00049f0c  /system/lib/libc.so (tgkill+12)
    #01 pc 00019cdf  /system/lib/libc.so (abort+50)
    #02 pc 0001e197  /system/lib/libc.so (__fortify_fatal+30)
    #03 pc 0001baf9  /system/lib/libc.so (__read_chk+48)
    #04 pc 0000165b  /system/xbin/crasher (do_action+534)
    #05 pc 000021e5  /system/xbin/crasher (main+100)
    #06 pc 000177a1  /system/lib/libc.so (__libc_init+48)
    #07 pc 00001110  /system/xbin/crasher (_start+96)

Bạn có thể tái tạo một thể hiện của loại tai nạn sử dụng crasher fortify .

Lỗi ngăn xếp được phát hiện bởi -fstack-protectionor

Của trình biên dịch -fstack-protector tùy chọn chèn kiểm tra vào chức năng với bộ đệm trên stack để bảo vệ chống vượt đệm. Tùy chọn này được bật theo mặc định cho mã nền tảng nhưng không bật cho ứng dụng. Khi tùy chọn này được kích hoạt, trình biên dịch cho biết thêm hướng dẫn để các chức năng mở đầu để viết một giá trị ngẫu nhiên chỉ quá khứ địa phương cuối cùng trên stack và chức năng bạt để đọc nó trở lại và kiểm tra xem nó không thay đổi. Nếu giá trị đó đã thay đổi, nó được ghi đè bởi một tràn bộ đệm, vì vậy các cuộc gọi lời bạt __stack_chk_fail để đăng nhập một thông điệp và hủy bỏ.

pid: 26717, tid: 26717, name: crasher  >>> crasher <<<
signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------
Abort message: 'stack corruption detected'
    r0 00000000  r1 0000685d  r2 00000006  r3 00000008
    r4 ffd516d8  r5 0000685d  r6 0000685d  r7 0000010c
    r8 00000000  r9 00000000  sl 00000000  fp ffd518bc
    ip 00000000  sp ffd516c8  lr ee63ece3  pc ee66ef0c  cpsr 000e0010

backtrace:
    #00 pc 00049f0c  /system/lib/libc.so (tgkill+12)
    #01 pc 00019cdf  /system/lib/libc.so (abort+50)
    #02 pc 0001e07d  /system/lib/libc.so (__libc_fatal+24)
    #03 pc 0004863f  /system/lib/libc.so (__stack_chk_fail+6)
    #04 pc 000013ed  /system/xbin/crasher (smash_stack+76)
    #05 pc 00001591  /system/xbin/crasher (do_action+280)
    #06 pc 00002219  /system/xbin/crasher (main+100)
    #07 pc 000177a1  /system/lib/libc.so (__libc_init+48)
    #08 pc 00001144  /system/xbin/crasher (_start+96)

Bạn có thể phân biệt này từ các loại hủy bỏ bởi sự hiện diện của __stack_chk_fail trong backtrace và cụ thể hủy bỏ tin nhắn.

Bạn có thể tái tạo một thể hiện của loại tai nạn sử dụng crasher smash-stack .

Seccomp SIGSYS từ một lệnh gọi hệ thống không được phép

Các seccomp hệ thống (đặc biệt là seccomp-BPF) hạn chế quyền truy cập vào các cuộc gọi hệ thống. Để biết thêm thông tin về seccomp cho các nhà phát triển nền tảng, xem bài đăng blog Seccomp lọc trong Android O . Một luồng thực hiện cuộc gọi hệ thống hạn chế sẽ nhận được tín hiệu SIGSYS với mã SYS_SECCOMP. Số cuộc gọi hệ thống sẽ được hiển thị trong dòng nguyên nhân, cùng với kiến ​​trúc. Điều quan trọng cần lưu ý là số cuộc gọi hệ thống khác nhau giữa các kiến ​​trúc. Ví dụ, readlinkat(2) hệ thống gọi là số 305 trên x86 nhưng 267 trên x86-64. Số cuộc gọi lại khác trên cả arm và arm64. Bởi vì số cuộc gọi hệ thống khác nhau giữa các kiến ​​trúc, thường dễ dàng sử dụng dấu vết ngăn xếp để tìm ra lệnh gọi hệ thống nào không được phép thay vì tìm kiếm số cuộc gọi hệ thống trong tiêu đề.

pid: 11046, tid: 11046, name: crasher  >>> crasher <<<
signal 31 (SIGSYS), code 1 (SYS_SECCOMP), fault addr --------
Cause: seccomp prevented call to disallowed arm system call 99999
    r0 cfda0444  r1 00000014  r2 40000000  r3 00000000
    r4 00000000  r5 00000000  r6 00000000  r7 0001869f
    r8 00000000  r9 00000000  sl 00000000  fp fffefa58
    ip fffef898  sp fffef888  lr 00401997  pc f74f3658  cpsr 600f0010

backtrace:
    #00 pc 00019658  /system/lib/libc.so (syscall+32)
    #01 pc 00001993  /system/bin/crasher (do_action+1474)
    #02 pc 00002699  /system/bin/crasher (main+68)
    #03 pc 0007c60d  /system/lib/libc.so (__libc_init+48)
    #04 pc 000011b0  /system/bin/crasher (_start_main+72)

Bạn có thể phân biệt các cuộc gọi hệ thống không được phép từ tai nạn khác do sự hiện diện của SYS_SECCOMP trên đường tín hiệu và mô tả trên dòng nguyên nhân.

Bạn có thể tái tạo một thể hiện của loại tai nạn sử dụng crasher seccomp .

Vi phạm bộ nhớ chỉ thực thi (chỉ Android 10)

Đối với arm64 chỉ trong Android 10, các phân đoạn thực thi của các tệp nhị phân và thư viện được ánh xạ thành chỉ thực thi trong bộ nhớ (không thể đọc) như một kỹ thuật tăng cường chống lại các cuộc tấn công tái sử dụng mã. Giảm thiểu này tương tác xấu với các giảm nhẹ khác và sau đó đã bị loại bỏ.

Làm cho mã nguyên nhân không đọc được cố ý và vô tình đọc vào bộ nhớ phân đoạn đánh dấu thực hiện chỉ để ném một SIGSEGV với mã SEGV_ACCERR . Điều này có thể xảy ra do lỗi, lỗ hổng bảo mật, dữ liệu bị trộn lẫn với mã (chẳng hạn như nhóm chữ) hoặc sự xem xét nội tâm của bộ nhớ có chủ ý.

Trình biên dịch giả định rằng mã và dữ liệu không được trộn lẫn với nhau, nhưng các vấn đề có thể phát sinh từ quá trình lắp ráp viết tay. Trong nhiều trường hợp này có thể được cố định bằng cách di chuyển các hằng số để một .data phần. Nếu mã mẫn là hoàn toàn cần thiết về phần mã thực thi, mprotect(2) nên được gọi là người đầu tiên đánh dấu sự có thể đọc được mã, và sau đó một lần nữa để đánh dấu nó không đọc được sau khi phẫu thuật xong.

pid: 2938, tid: 2940, name: crasher64  >>> crasher64 <<<
signal 11 (SIGSEGV), code 2 (SEGV_ACCERR), fault addr 0x5f2ced24a8
Cause: execute-only (no-read) memory access error; likely due to data in .text.
    x0  0000000000000000  x1  0000005f2cecf21f  x2  0000000000000078  x3  0000000000000053
    x4  0000000000000074  x5  8000000000000000  x6  ff71646772607162  x7  00000020dcf0d16c
    x8  0000005f2ced24a8  x9  000000781251c55e  x10 0000000000000000  x11 0000000000000000
    x12 0000000000000014  x13 ffffffffffffffff  x14 0000000000000002  x15 ffffffffffffffff
    x16 0000005f2ced52f0  x17 00000078125c0ed8  x18 0000007810e8e000  x19 00000078119fbd50
    x20 00000078125d6020  x21 00000078119fbd50  x22 00000b7a00000b7a  x23 00000078119fbdd8
    x24 00000078119fbd50  x25 00000078119fbd50  x26 00000078119fc018  x27 00000078128ea020
    x28 00000078119fc020  x29 00000078119fbcb0
    sp  00000078119fba40  lr  0000005f2ced1b94  pc  0000005f2ced1ba4

backtrace:
      #00 pc 0000000000003ba4  /system/bin/crasher64 (do_action+2348)
      #01 pc 0000000000003234  /system/bin/crasher64 (thread_callback+44)
      #02 pc 00000000000e2044  /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+36)
      #03 pc 0000000000083de0  /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64)

Bạn có thể phân biệt vi phạm bộ nhớ chỉ thực thi với các lỗi khác bằng dòng nguyên nhân.

Bạn có thể tái tạo một thể hiện của loại tai nạn sử dụng crasher xom .

Fdsan phát hiện lỗi

Trình vệ sinh trình mô tả tệp fdsan của Android giúp phát hiện các lỗi thường gặp với trình mô tả tệp như use-after-close và double-close. Xem các tài liệu hướng dẫn fdsan để biết thêm chi tiết về gỡ lỗi (và tránh) lớp này lỗi.

pid: 32315, tid: 32315, name: crasher64  >>> crasher64 <<<
signal 35 (), code -1 (SI_QUEUE), fault addr --------
Abort message: 'attempted to close file descriptor 3, expected to be unowned, actually owned by FILE* 0x7d8e413018'
    x0  0000000000000000  x1  0000000000007e3b  x2  0000000000000023  x3  0000007fe7300bb0
    x4  3033313465386437  x5  3033313465386437  x6  3033313465386437  x7  3831303331346538
    x8  00000000000000f0  x9  0000000000000000  x10 0000000000000059  x11 0000000000000034
    x12 0000007d8ebc3a49  x13 0000007fe730077a  x14 0000007fe730077a  x15 0000000000000000
    x16 0000007d8ec9a7b8  x17 0000007d8ec779f0  x18 0000007d8f29c000  x19 0000000000007e3b
    x20 0000000000007e3b  x21 0000007d8f023020  x22 0000007d8f3b58dc  x23 0000000000000001
    x24 0000007fe73009a0  x25 0000007fe73008e0  x26 0000007fe7300ca0  x27 0000000000000000
    x28 0000000000000000  x29 0000007fe7300c90
    sp  0000007fe7300860  lr  0000007d8ec2f22c  pc  0000007d8ec2f250

backtrace:
      #00 pc 0000000000088250  /bionic/lib64/libc.so (fdsan_error(char const*, ...)+384)
      #01 pc 0000000000088060  /bionic/lib64/libc.so (android_fdsan_close_with_tag+632)
      #02 pc 00000000000887e8  /bionic/lib64/libc.so (close+16)
      #03 pc 000000000000379c  /system/bin/crasher64 (do_action+1316)
      #04 pc 00000000000049c8  /system/bin/crasher64 (main+96)
      #05 pc 000000000008021c  /bionic/lib64/libc.so (_start_main)

Bạn có thể phân biệt này từ các loại hủy bỏ bởi sự hiện diện của fdsan_error trong backtrace và cụ thể hủy bỏ tin nhắn.

Bạn có thể tái tạo một thể hiện của loại tai nạn sử dụng crasher fdsan_file hoặc crasher fdsan_dir .

Điều tra bãi chứa va chạm

Nếu bạn không có một vụ tai nạn cụ thể mà bạn đang điều tra ngay bây giờ, nguồn nền tảng bao gồm một công cụ để thử nghiệm debuggerd gọi Crasher. Nếu bạn mm trong system/core/debuggerd/ bạn sẽ nhận được cả một crashercrasher64 trên con đường của bạn (sau này cho phép bạn kiểm tra tai nạn 64-bit). Crasher có thể gặp sự cố theo nhiều cách thú vị dựa trên các đối số dòng lệnh mà bạn cung cấp. Sử dụng crasher --help để xem lựa chọn được hỗ trợ.

Để giới thiệu các phần khác nhau trong kết xuất sự cố, chúng ta hãy làm việc thông qua kết xuất sự cố ví dụ này:

*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
Build fingerprint: 'Android/aosp_flounder/flounder:5.1.51/AOSP/enh08201009:eng/test-keys'
Revision: '0'
ABI: 'arm'
pid: 1656, tid: 1656, name: crasher  >>> crasher <<<
signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------
Abort message: 'some_file.c:123: some_function: assertion "false" failed'
    r0 00000000  r1 00000678  r2 00000006  r3 f70b6dc8
    r4 f70b6dd0  r5 f70b6d80  r6 00000002  r7 0000010c
    r8 ffffffed  r9 00000000  sl 00000000  fp ff96ae1c
    ip 00000006  sp ff96ad18  lr f700ced5  pc f700dc98  cpsr 400b0010
backtrace:
    #00 pc 00042c98  /system/lib/libc.so (tgkill+12)
    #01 pc 00041ed1  /system/lib/libc.so (pthread_kill+32)
    #02 pc 0001bb87  /system/lib/libc.so (raise+10)
    #03 pc 00018cad  /system/lib/libc.so (__libc_android_abort+34)
    #04 pc 000168e8  /system/lib/libc.so (abort+4)
    #05 pc 0001a78f  /system/lib/libc.so (__libc_fatal+16)
    #06 pc 00018d35  /system/lib/libc.so (__assert2+20)
    #07 pc 00000f21  /system/xbin/crasher
    #08 pc 00016795  /system/lib/libc.so (__libc_init+44)
    #09 pc 00000abc  /system/xbin/crasher
Tombstone written to: /data/tombstones/tombstone_06
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***

Dòng dấu hoa thị với khoảng trắng rất hữu ích nếu bạn đang tìm kiếm nhật ký cho các sự cố gốc. Chuỗi "*** ***" hiếm khi hiển thị trong nhật ký khác với khi bắt đầu sự cố gốc.

Build fingerprint:
'Android/aosp_flounder/flounder:5.1.51/AOSP/enh08201009:eng/test-keys'

Dấu vân tay cho phép bạn xác định chính xác bản dựng mà sự cố đã xảy ra. Đây là chính xác giống như các ro.build.fingerprint sở hữu hệ thống.

Revision: '0'

Bản sửa đổi đề cập đến phần cứng hơn là phần mềm. Điều này thường không được sử dụng nhưng có thể hữu ích để giúp bạn tự động bỏ qua các lỗi được xác định là do phần cứng kém gây ra. Đây là chính xác giống như các ro.revision sở hữu hệ thống.

ABI: 'arm'

ABI là một trong số arm, arm64, x86 hoặc x86-64. Điều này chủ yếu hữu ích cho việc stack kịch bản nêu trên, để nó biết những gì toolchain để sử dụng.

pid: 1656, tid: 1656, name: crasher >>> crasher <<<

Dòng này xác định chuỗi cụ thể trong quá trình bị lỗi. Trong trường hợp này, đó là luồng chính của quy trình, vì vậy ID quy trình và ID luồng phù hợp. Tên đầu tiên là tên luồng, và tên được bao quanh bởi >>> và <<< là tên tiến trình. Đối với một ứng dụng, tên quy trình thường là tên gói đủ điều kiện (chẳng hạn như com.facebook.katana), rất hữu ích khi gửi lỗi hoặc cố gắng tìm ứng dụng trong Google Play. Pid và tid cũng có thể hữu ích trong việc tìm kiếm các dòng nhật ký liên quan trước khi xảy ra sự cố.

signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------

Dòng này cho bạn biết tín hiệu nào (SIGABRT) đã được nhận và thông tin thêm về cách nhận tín hiệu (SI_TKILL). Các tín hiệu báo cáo của debuggerd là SIGABRT, SIGBUS, SIGFPE, SIGILL, SIGSEGV, và SIGTRAP. Các mã dành riêng cho tín hiệu khác nhau dựa trên tín hiệu cụ thể.

Abort message: 'some_file.c:123: some_function: assertion "false" failed'

Không phải tất cả các sự cố sẽ có một dòng thông báo hủy bỏ, nhưng hủy bỏ sẽ có. Điều này được tự động thu thập từ dòng cuối cùng của đầu ra logcat nghiêm trọng cho pid / tid này và trong trường hợp cố ý hủy bỏ có thể đưa ra lời giải thích tại sao chương trình tự giết chính nó.

r0 00000000 r1 00000678 r2 00000006 r3 f70b6dc8
r4 f70b6dd0 r5 f70b6d80 r6 00000002 r7 0000010c
r8 ffffffed r9 00000000 sl 00000000 fp ff96ae1c
ip 00000006 sp ff96ad18 lr f700ced5 pc f700dc98 cpsr 400b0010

Kết xuất thanh ghi hiển thị nội dung của các thanh ghi CPU tại thời điểm nhận được tín hiệu. (Phần này rất khác nhau giữa các ABI.) Mức độ hữu ích của chúng sẽ phụ thuộc vào sự cố chính xác.

backtrace:
    #00 pc 00042c98 /system/lib/libc.so (tgkill+12)
    #01 pc 00041ed1 /system/lib/libc.so (pthread_kill+32)
    #02 pc 0001bb87 /system/lib/libc.so (raise+10)
    #03 pc 00018cad /system/lib/libc.so (__libc_android_abort+34)
    #04 pc 000168e8 /system/lib/libc.so (abort+4)
    #05 pc 0001a78f /system/lib/libc.so (__libc_fatal+16)
    #06 pc 00018d35 /system/lib/libc.so (__assert2+20)
    #07 pc 00000f21 /system/xbin/crasher
    #08 pc 00016795 /system/lib/libc.so (__libc_init+44)
    #09 pc 00000abc /system/xbin/crasher

Dấu lùi cho bạn biết chúng ta đã ở đâu trong mã tại thời điểm gặp sự cố. Cột đầu tiên là số khung (khớp với kiểu của gdb trong đó khung sâu nhất là 0). Các giá trị PC liên quan đến vị trí của thư viện được chia sẻ hơn là địa chỉ tuyệt đối. Cột tiếp theo là tên của vùng được ánh xạ (thường là thư viện dùng chung hoặc tệp thực thi, nhưng có thể không phải là mã do JIT biên dịch). Cuối cùng, nếu các ký hiệu có sẵn, ký hiệu mà giá trị PC tương ứng sẽ được hiển thị, cùng với phần bù vào ký hiệu đó theo byte. Bạn có thể sử dụng kết hợp với objdump(1) để tìm hướng dẫn lắp ráp tương ứng.

Đọc bia mộ

Tombstone written to: /data/tombstones/tombstone_06

Điều này cho bạn biết nơi debuggerd viết thông tin thêm. debuggerd sẽ tiếp tục lên đến 10 ngôi mộ, vòng qua một số 00-09 và ghi đè lên ngôi mộ hiện khi cần thiết.

Bia mộ chứa thông tin tương tự như bãi rác, cùng với một số thông tin bổ sung. Ví dụ, nó bao gồm vết lùi cho tất cả các chủ đề (không chỉ là sợi chỉ bị rơi), các thanh ghi dấu chấm động, bãi chồng thô, và bộ nhớ bãi xung quanh các địa chỉ trong thanh ghi. Một cách hữu ích nhất nó cũng bao gồm một bản đồ bộ nhớ đầy đủ (tương tự như /proc/ pid /maps ). Dưới đây là một ví dụ được chú thích từ sự cố quy trình ARM 32-bit:

memory map: (fault address prefixed with --->)
--->ab15f000-ab162fff r-x 0 4000 /system/xbin/crasher (BuildId:
b9527db01b5cf8f5402f899f64b9b121)

Có hai điều cần lưu ý ở đây. Đầu tiên là dòng này có tiền tố là "--->". Bản đồ hữu ích nhất khi sự cố của bạn không chỉ là một tham chiếu con trỏ rỗng. Nếu địa chỉ lỗi nhỏ, có thể đó là một số biến thể của tham chiếu con trỏ null. Nếu không, nhìn vào bản đồ xung quanh địa chỉ lỗi thường có thể cung cấp cho bạn manh mối về những gì đã xảy ra. Một số vấn đề có thể xảy ra có thể nhận ra bằng cách xem bản đồ bao gồm:

  • Đọc / ghi qua phần cuối của một khối bộ nhớ.
  • Đọc / ghi trước khi bắt đầu một khối bộ nhớ.
  • Cố gắng thực thi mã không phải.
  • Đang chạy ra cuối một ngăn xếp.
  • Cố gắng ghi vào mã (như trong ví dụ trên).

Điều thứ hai cần lưu ý là tệp thực thi và tệp thư viện được chia sẻ sẽ hiển thị BuildId (nếu có) trong Android 6.0 trở lên, vì vậy bạn có thể xem chính xác phiên bản mã của mình bị lỗi. Hệ nhị phân nền tảng bao gồm BuildId theo mặc định kể từ Android 6.0; NDK r12 và cao tự động chuyển -Wl,--build-id để mối liên kết quá.

ab163000-ab163fff r--      3000      1000  /system/xbin/crasher
ab164000-ab164fff rw-         0      1000
f6c80000-f6d7ffff rw-         0    100000  [anon:libc_malloc]

Trên Android, heap không nhất thiết phải là một vùng duy nhất. Vùng Heap sẽ được dán nhãn [anon:libc_malloc] .

f6d82000-f6da1fff r--         0     20000  /dev/__properties__/u:object_r:logd_prop:s0
f6da2000-f6dc1fff r--         0     20000  /dev/__properties__/u:object_r:default_prop:s0
f6dc2000-f6de1fff r--         0     20000  /dev/__properties__/u:object_r:logd_prop:s0
f6de2000-f6de5fff r-x         0      4000  /system/lib/libnetd_client.so (BuildId: 08020aa06ed48cf9f6971861abf06c9d)
f6de6000-f6de6fff r--      3000      1000  /system/lib/libnetd_client.so
f6de7000-f6de7fff rw-      4000      1000  /system/lib/libnetd_client.so
f6dec000-f6e74fff r-x         0     89000  /system/lib/libc++.so (BuildId: 8f1f2be4b37d7067d366543fafececa2) (load base 0x2000)
f6e75000-f6e75fff ---         0      1000
f6e76000-f6e79fff r--     89000      4000  /system/lib/libc++.so
f6e7a000-f6e7afff rw-     8d000      1000  /system/lib/libc++.so
f6e7b000-f6e7bfff rw-         0      1000  [anon:.bss]
f6e7c000-f6efdfff r-x         0     82000  /system/lib/libc.so (BuildId: d189b369d1aafe11feb7014d411bb9c3)
f6efe000-f6f01fff r--     81000      4000  /system/lib/libc.so
f6f02000-f6f03fff rw-     85000      2000  /system/lib/libc.so
f6f04000-f6f04fff rw-         0      1000  [anon:.bss]
f6f05000-f6f05fff r--         0      1000  [anon:.bss]
f6f06000-f6f0bfff rw-         0      6000  [anon:.bss]
f6f0c000-f6f21fff r-x         0     16000  /system/lib/libcutils.so (BuildId: d6d68a419dadd645ca852cd339f89741)
f6f22000-f6f22fff r--     15000      1000  /system/lib/libcutils.so
f6f23000-f6f23fff rw-     16000      1000  /system/lib/libcutils.so
f6f24000-f6f31fff r-x         0      e000  /system/lib/liblog.so (BuildId: e4d30918d1b1028a1ba23d2ab72536fc)
f6f32000-f6f32fff r--      d000      1000  /system/lib/liblog.so
f6f33000-f6f33fff rw-      e000      1000  /system/lib/liblog.so

Thông thường, một thư viện được chia sẻ có ba mục nhập liền kề. Một là có thể đọc và thực thi (mã), một là chỉ đọc (dữ liệu chỉ đọc) và một là đọc-ghi (dữ liệu có thể thay đổi). Các chương trình cột đầu tiên địa chỉ dao động cho việc lập bản đồ, cột thứ hai cho phép (trong Unix thường ls(1) phong cách), cột thứ ba bù đắp vào các tập tin (trong hex), cột thứ tư kích thước của khu vực ( trong hex), và cột thứ năm của tệp (hoặc tên vùng khác).

f6f34000-f6f53fff r-x         0     20000  /system/lib/libm.so (BuildId: 76ba45dcd9247e60227200976a02c69b)
f6f54000-f6f54fff ---         0      1000
f6f55000-f6f55fff r--     20000      1000  /system/lib/libm.so
f6f56000-f6f56fff rw-     21000      1000  /system/lib/libm.so
f6f58000-f6f58fff rw-         0      1000
f6f59000-f6f78fff r--         0     20000  /dev/__properties__/u:object_r:default_prop:s0
f6f79000-f6f98fff r--         0     20000  /dev/__properties__/properties_serial
f6f99000-f6f99fff rw-         0      1000  [anon:linker_alloc_vector]
f6f9a000-f6f9afff r--         0      1000  [anon:atexit handlers]
f6f9b000-f6fbafff r--         0     20000  /dev/__properties__/properties_serial
f6fbb000-f6fbbfff rw-         0      1000  [anon:linker_alloc_vector]
f6fbc000-f6fbcfff rw-         0      1000  [anon:linker_alloc_small_objects]
f6fbd000-f6fbdfff rw-         0      1000  [anon:linker_alloc_vector]
f6fbe000-f6fbffff rw-         0      2000  [anon:linker_alloc]
f6fc0000-f6fc0fff r--         0      1000  [anon:linker_alloc]
f6fc1000-f6fc1fff rw-         0      1000  [anon:linker_alloc_lob]
f6fc2000-f6fc2fff r--         0      1000  [anon:linker_alloc]
f6fc3000-f6fc3fff rw-         0      1000  [anon:linker_alloc_vector]
f6fc4000-f6fc4fff rw-         0      1000  [anon:linker_alloc_small_objects]
f6fc5000-f6fc5fff rw-         0      1000  [anon:linker_alloc_vector]
f6fc6000-f6fc6fff rw-         0      1000  [anon:linker_alloc_small_objects]
f6fc7000-f6fc7fff rw-         0      1000  [anon:arc4random _rsx structure]
f6fc8000-f6fc8fff rw-         0      1000  [anon:arc4random _rs structure]
f6fc9000-f6fc9fff r--         0      1000  [anon:atexit handlers]
f6fca000-f6fcafff ---         0      1000  [anon:thread signal stack guard page]

Kể từ Android 5.0, thư viện C đặt tên cho hầu hết các vùng được ánh xạ ẩn danh của nó, do đó sẽ có ít vùng bí ẩn hơn.

f6fcb000-f6fccfff rw- 0 2000 [stack:5081]

Khu vực có tên là [stack: tid ] là ngăn xếp cho các chủ đề nhất định.

f6fcd000-f702afff r-x         0     5e000  /system/bin/linker (BuildId: 84f1316198deee0591c8ac7f158f28b7)
f702b000-f702cfff r--     5d000      2000  /system/bin/linker
f702d000-f702dfff rw-     5f000      1000  /system/bin/linker
f702e000-f702ffff rw-         0      2000
f7030000-f7030fff r--         0      1000
f7031000-f7032fff rw-         0      2000
ffcd7000-ffcf7fff rw-         0     21000
ffff0000-ffff0fff r-x         0      1000  [vectors]

Cho dù bạn thấy [vector] hoặc [vdso] phụ thuộc vào kiến trúc. Sử dụng ARM [vector] , trong khi tất cả các kiến trúc khác sử dụng [vdso] .