What should we do when meet a crash in android

來源:互聯網
上載者:User
What should we do when meet a crash in android?

原帖地址:http://leave001.blog.163.com/blog/static/1626912932011226105512484/

製造一個crash

為了示範的目的,我在libsensors的open_sensors_device中故意製造了一個crash:

static int open_sensors_device(const struct hw_module_t* module, const char* name,

        struct hw_device_t** device)

{

    int status = -EINVAL;

    //if our sensor system is ready,commented next line

    //return status;

    char* ptr = 0;

    *ptr = 0;

    // ....

}

這裡ptr指向0地址,但後面卻往這個0地址寫0,因此會crash。crash時,logcat可以看到android列印的backtrace:

I/SystemServer( 1046): Sensor Service

I/DEBUG   (  971): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***

I/DEBUG   (  971): Build fingerprint: 'Questers/kylin/kylin/aspen168:2.2.1/FRG83/builder.20110307.131914:user/release-keys'

I/DEBUG   (  971): pid: 1046, tid: 1059  >>> system_server <<<

I/DEBUG   (  971): signal 11 (SIGSEGV), fault addr 00000000

I/DEBUG   (  971):  r0 8150218c  r1 81501250  r2 ae205500  r3 00000000

I/DEBUG   (  971):  r4 ae203d5b  r5 8150210c  r6 43891f6c  r7 42084eb0

I/DEBUG   (  971):  r8 4a570b80  r9 42084ea8  10 42084e94  fp 0011f3e0

I/DEBUG   (  971):  ip a7f0110c  sp 4a570b50  lr ae203247  pc 815009ba  cpsr a0000030

I/DEBUG   (  971):          #00  pc 000009ba  /system/lib/hw/sensors.default.so

I/DEBUG   (  971):          #01  pc 00003244  /system/lib/libandroid_servers.so

I/DEBUG   (  971):          #02  pc 00011cf4  /system/lib/libdvm.so

I/DEBUG   (  971):          #03  pc 0003f194  /system/lib/libdvm.so

I/DEBUG   (  971):          #04  pc 00016cb8  /system/lib/libdvm.so

I/DEBUG   (  971):          #05  pc 0001d604  /system/lib/libdvm.so

I/DEBUG   (  971):          #06  pc 0001c49c  /system/lib/libdvm.so

I/DEBUG   (  971):          #07  pc 00055374  /system/lib/libdvm.so

I/DEBUG   (  971):          #08  pc 0005558a  /system/lib/libdvm.so

I/DEBUG   (  971):          #09  pc 00049672  /system/lib/libdvm.so

I/DEBUG   (  971):          #10  pc 000113fc  /system/lib/libc.so

I/DEBUG   (  971):          #11  pc 00010ee0  /system/lib/libc.so

I/DEBUG   (  971): 

I/DEBUG   (  971): code around pc:

I/DEBUG   (  971): 81500998 600b189b 46c04770 00001772 fffffef4 

I/DEBUG   (  971): 815009a8 4d2bb5f0 492b1c0c b083447d 90012300 

I/DEBUG   (  971): 815009b8 701b1869 1c161c20 efa8f7ff d11f1e07 

I/DEBUG   (  971): 815009c8 f7ff205c 2100ef62 1c04225c ef92f7ff 

I/DEBUG   (  971): 815009d8 21014821 6562424a 60676020 4a20491f 

I/DEBUG   (  971): 

I/DEBUG   (  971): code around lr:

I/DEBUG   (  971): ae203224 b082480e 1820447c f7fea901 2800eaf6 

I/DEBUG   (  971): ae203234 9801d10f 4a0b490a 18616943 681b18a2 

I/DEBUG   (  971): ae203244 28004798 9801d105 1d034669 47a06fdc 

I/DEBUG   (  971): ae203254 2000e000 bd10b002 00001ee8 ffffec3f 

I/DEBUG   (  971): ae203264 ffffec47 000003ec 4e3db5f0 4c3d1c05 

I/DEBUG   (  971): 

I/DEBUG   (  971): stack:

I/DEBUG   (  971):     4a570b10  4a570b80  

I/DEBUG   (  971):     4a570b14  42084e74  

I/DEBUG   (  971):     4a570b18  0027be10  [heap]

I/DEBUG   (  971):     4a570b1c  0011f3e0  [heap]

I/DEBUG   (  971):     4a570b20  00000001  

I/DEBUG   (  971):     4a570b24  00000007  

I/DEBUG   (  971):     4a570b28  00000000  

I/DEBUG   (  971):     4a570b2c  00000000  

I/DEBUG   (  971):     4a570b30  420ce5c0  /dev/ashmem/dalvik-LinearAlloc (deleted)

I/DEBUG   (  971):     4a570b34  0011f3e0  [heap]

I/DEBUG   (  971):     4a570b38  0027be10  [heap]

I/DEBUG   (  971):     4a570b3c  422962b0  /dev/ashmem/dalvik-LinearAlloc (deleted)

I/DEBUG   (  971):     4a570b40  4a570bb0  

I/DEBUG   (  971):     4a570b44  000000d0  

I/DEBUG   (  971):     4a570b48  df002777  

I/DEBUG   (  971):     4a570b4c  e3a070ad  

I/DEBUG   (  971): #00 4a570b50  422962b0  /dev/ashmem/dalvik-LinearAlloc (deleted)

I/DEBUG   (  971):     4a570b54  8150218c  /system/lib/hw/sensors.default.so

I/DEBUG   (  971):     4a570b58  45d7fd20  /dev/ashmem/mspace/dalvik-heap/2 (deleted)

I/DEBUG   (  971):     4a570b5c  ae205114  /system/lib/libandroid_servers.so

I/DEBUG   (  971):     4a570b60  00000004  

I/DEBUG   (  971):     4a570b64  43891f6c  /data/dalvik-cache/system@framework@services.jar@classes.dex

I/DEBUG   (  971):     4a570b68  42084eb0  

I/DEBUG   (  971):     4a570b6c  ae203247  /system/lib/libandroid_servers.so

I/DEBUG   (  971): #01 4a570b70  438a922c  /data/dalvik-cache/system@framework@services.jar@classes.dex

I/DEBUG   (  971):     4a570b74  8150218c  /system/lib/hw/sensors.default.so

I/DEBUG   (  971):     4a570b78  4a570ba0  

I/DEBUG   (  971):     4a570b7c  aca11cf8  /system/lib/libdvm.so

D/Zygote  (  973): Process 1046 terminated by signal (11)

有用的資訊

我們可以關注以下五處:

1. 哪個進程crash了

這裡為/system/bin/system_server出了問題,它的pid為1046。

2. crash時cpu拋出的訊號

比如這裡是11(SEGV),表示段錯誤,一般為程式指令訪問非法地址時產生。其它的訊號的意義可以參考《Unix環境進階編程》。另外,這個數字和名字間的對應關係可以用kill -l列出:

# kill -l

1    HUP Hangup                        17   CHLD Child exited            

2    INT Interrupt                     18   CONT Continue                

3   QUIT Quit                          19   STOP Stopped (signal)        

4    ILL Illegal instruction           20   TSTP Stopped                 

5   TRAP Trap                          21   TTIN Stopped (tty input)     

6   ABRT Aborted                       22   TTOU Stopper (tty output)    

7    BUS Bus error                     23    URG Urgent I/O condition    

8    FPE Floating point exception      24   XCPU CPU time limit exceeded 

9   KILL Killed                        25   XFSZ File size limit exceeded

10   USR1 User signal 1                 26 VTALRM Virtual timer expired   

11   SEGV Segmentation fault            27   PROF Profiling timer expired 

12   USR2 User signal 2                 28  WINCH Window size changed     

13   PIPE Broken pipe                   29     IO I/O possible            

14   ALRM Alarm clock                   30    PWR Power failure           

15   TERM Terminated                    31    SYS Bad system call         

16 STKFLT Stack fault     


3. 發生錯誤的地址

如上面的log列印出的“fault addr 00000000",表示cpu對這個地址作讀寫操作除了異常。NULL(0)地址為OS預留的地址,作指標初始化用途,不允許程式進行讀寫。

4. PC指標

如上面列印出的

#00  pc 000009ba  /system/lib/hw/sensors.default.so

#01  pc 00003244  /system/lib/libandroid_servers.so

表示出錯時cpu的指令指標指向這個地址。可以用後面介紹的方法由地址找出代碼位置。

5. 棧資訊

android會dump出棧的內容。在unix/linux中,一般情況下棧會向低地址位置移動,android也不例外。在上面dump的資訊中,越靠上(地址越小)表示這是棧頂位置,越往下表示棧底。

另外,dump的資訊中有三列:

4a570b54  8150218c  /system/lib/hw/sensors.default.so

第一列:表示棧空間的地址。這裡為4a570b54

第二列:這個棧單元中的內容。這裡為8150218c

第三列:表示該內容對應的代碼。若無text資訊,則此處顯示為空白。這裡為/system/lib/hw/sensors.default.so

最後需要注意的是,這裡顯示的地址為完整形式,即基地址+位移量。基地址可以從/proc/<pid>/maps中看出(<pid>為crash進程對應的pid):

cat /proc/1059/maps | grep "sensors.default.so"

81500000-81502000 r-xp 00000000 00:0f 953        /system/lib/hw/sensors.default.so

81502000-81503000 rwxp 00002000 00:0f 953        /system/lib/hw/sensors.default.so

這裡上面一行(不可寫)為sensors.default.so的文本段,下一行為資料區段(可讀寫)。可以看到sensors.default.so被映射到了system_server進程的81500000~81503000地址空間中。將代碼完整地址8150218c減去基地址81500000,可以得到libc.so中的位移地址0000218c。另外注意到,8150218c映射到資料區段,說明出問題時棧儲存有
sensors.default.so中某一個函數中的局部變數。( 為什嗎??)

由地址得到符號資訊

給定一個地址,可以找出它對應的符號資訊,以便分析。

找到大致的函數位置

guang@leave001:~/froyo_0308$ vendor/qsts/toolchain/arm-linux-4.1.1/bin/arm-linux-objdump -t out/target/product/kylin/symbols/system/lib/sensors.default.so | sort > list.txt

注意,這裡需要找到out下symbols中的so檔案,因為它的symbol資訊沒有被strip掉。list.txt中包含了按照地址排序的符號資訊。根據sensors.default.so出錯的地址000009ba,可以找到符號資訊:

00000990 <sensors__get_sensors_list>:

000009a8 <open_sensors_device>:

00000a8c <pick_sensor>:

可以看到跟000009ba比較接近的地址為000009a8,因此可以判斷出錯的函數為open_sensors_device。

找出具體位置

objdump -t僅列印簡單的資訊。-S參數可以顯示詳細資料,輸出中包含c和彙編代碼:

guang@leave001:~/froyo_0308$ vendor/qsts/toolchain/arm-linux-4.1.1/bin/arm-linux-objdump -S out/target/product/kylin/symbols/system/lib/sensors.default.so > list.txt

在產生的list.txt中找到函數open_sensors_device,下面可以看到c代碼和彙編:

static int open_sensors_device(const struct hw_module_t* module, const char* name,

        struct hw_device_t** device)

{

     9a8:   b5f0        push    {r4, r5, r6, r7, lr}

    int status = -EINVAL;

    //if our sensor system is ready,commented next line

    //return status;

    char* ptr = 0;

    *ptr = 0;

    if (!strcmp(name, SENSORS_HARDWARE_CONTROL)) {

     9aa:   4d2b        ldr r5, [pc, #172]  (a58 <.text+0xc8>)

     9ac:   1c0c        adds    r4, r1, #0

     9ae:   492b        ldr r1, [pc, #172]  (a5c <.text+0xcc>)

     9b0:   447d        add r5, pc

     9b2:   b083        sub sp, #12

     9b4:   2300        movs    r3, #0

     9b6:   9001        str r0, [sp, #4]

     9b8:   1869        adds    r1, r5, r1

     9ba:   701b        strb    r3, [r3, #0]

     9bc:   1c20        adds    r0, r4, #0

     9be:   1c16        adds    r6, r2, #0

     9c0:   f7ff efa8   blx 914 <.text-0x7c>

     9c4:   1e07        subs    r7, r0, #0

     9c6:   d11f        bne.n   a08 <open_sensors_device+0x60>

出錯的地址為09ba,這裡的彙編代碼為

9ba:   701b        strb    r3, r3, #0

r3, #0意思是把常數0往r3儲存的地址傳送,而r3在前面被初始化為0地址,因此可以判斷出是上面的c代碼出了問題。

不幸的是,對於c++產生的so,輸出的彙編和c代碼跟地址對不上,因此不容易找到具體位置。還有,有時出錯的原因不容易從上面的方法分析出來,這時只能藉助這個方法來縮小代碼範圍,通過列印和檢視代碼來慢慢分析。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.