android I/DEBUG堆疊資訊

jackie_gnu發表於2011-11-07
 

堆疊錯誤資訊:

I/DEBUG   (   30): r0 afd4d4a4  r1 ffffffff  r2 7fffffff r3 afd4d4a4

I/DEBUG   (   30): r4 00000000  r5 ffffffff  r6 00000001 r7 be9f6ccc

I/DEBUG   (   30): r8 00000000  r9 00000000  10 00000000 fp 00000000

I/DEBUG   (   30): ip afd11fcd  sp be9f6c38  lr afd107f4 pc afd107fc  cpsr 80000010

I/DEBUG   (   30):         #00  pc 000107fc  /system/lib/libc.so

I/DEBUG   (   30):         #01  pc 0001ccfe  /system/lib/libdtvservice.so

I/DEBUG   (   30):         #02  pc 0001c646  /system/lib/libdtvservice.so

I/DEBUG   (   30):         #03  pc 0001937e  /system/lib/libdtvservice.so

I/DEBUG   (   30):         #04  pc 000110f8  /system/lib/libdtvservice.so

I/DEBUG   (   30):         #05  pc 000115a8 /system/lib/libdtvservice.so

I/DEBUG   (   30):         #06  pc 00008852  /system/bin/dtvserver

I/DEBUG   (   30):         #07  pc 00014dc8  /system/lib/libc.so

 

……

方法一:

1.將上面這段資訊複製到一個新建的檔案中,並儲存。例如:test-dtvserver.txt.

 

2.用panic.py工具解析這段錯誤資訊,panic.py工具的位置為~/android/

// 工具在附件中

執行:

[maw@localhost android]$ panic.py  test-stack.txt

read file ok

stop search

pr-support.c:258              __gnu_unwind_execute

posix_thread.c:97             destroy_posix_thread

thread.c:293                  thread_destroy

workpool.c:215                work_pool_uninitialize

dtvserver.c:203               dtvs_finalize

dtvserver.c:179               dtvs_initialize

DtvServer.cpp:19              main

dlmalloc.c:3890               tmalloc_small

 

這個就是結果。

 

使用panic.py的環境問題

 

1.要有arm-eabi-addr2line工具   ~/android/prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/

2.在system/lib/中要有相應的庫檔案

3.panic.py的存放位置要正確~/android/,也可以自己修改panic.py工具的程式碼,放在其他地方.

 

 

方法二:

如果沒有arm-eabi-addr2line工具,但是有arm-eabi-objdump工具

就用第二種方法。

I/DEBUG   (   30):         #00  pc 000107fc  /system/lib/libc.so

I/DEBUG   (   30):         #01  pc 0001ccfe  /system/lib/libdtvservice.so

I/DEBUG   (   30):         #02  pc 0001c646  /system/lib/libdtvservice.so

I/DEBUG   (   30):         #03  pc 0001937e  /system/lib/libdtvservice.so

I/DEBUG   (   30):         #04  pc 000110f8  /system/lib/libdtvservice.so

I/DEBUG   (   30):         #05  pc 000115a8  /system/lib/libdtvservice.so

I/DEBUG   (   30):         #06  pc 00008852  /system/bin/dtvserver

I/DEBUG   (   30):         #07  pc 00014dc8  /system/lib/libc.so

 

1.用objdump工具將上面這些對應的庫檔案反彙編:

執行:arm-eabi-objdump –dS libc.so > libc.dump

//這些庫檔案路徑在out/target/product/generic/obj/SHARED_LIBRARIES/ 

 

2.開啟反彙編後的庫檔案。例如:libc.dump。

找到上面錯誤碼提示的地址。例如000107fc。

在這裡我們可以找到這行指令所在的函式和檔案

以此類推,依次找出這些錯誤碼對應的函式和檔案,就可以知道是哪一個函式呼叫路線出問題了。

 

panic.py程式碼

#!/usr/bin/python

# stack symbol parser

 

import os

import string

import sys

 

#define android product name 這個視情況而定在out/target/product資料夾下

ANDROID_PRODUCT_NAME = 'generic'

#ANDROID_PRODUCT_NAME = 'smdk6410'

 

#這裡可以修改panic.py工具的存放位置

ANDROID_WORKSPACE = os.getcwd()+"/"

 

# addr2line tool path and symbol path

addr2line_tool = ANDROID_WORKSPACE +'prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/arm-eabi-addr2line'

symbol_dir = ANDROID_WORKSPACE + 'out/target/product/'+ ANDROID_PRODUCT_NAME +'/symbols'

symbol_bin = symbol_dir + '/system/bin/'

symbol_lib = symbol_dir + '/system/lib/'

 

class ReadLog:

    def__init__(self,filename):

       self.logname = filename

    defparse(self):

        f =file(self.logname,'r')

        lines =f.readlines()

        if lines!= []:

           print 'read file ok'

        else:

           print 'read file failed'

        result=[]

        for linein lines:

            ifline.find('stack') != -1:

               print 'stop search'

                break

            elifline.find('system') != -1:

               #print 'find one item' + line

               result.append(line)

        returnresult

 

class ParseContent:

    def__init__(self,addr,lib):

           self.address = addr # pc address

           self.exename = lib  # executableor shared library

    defaddr2line(self):

        cmd =addr2line_tool + " -C -f -s -e " + symbol_dir + self.exename + "" + self.address

        #printcmd

        stream =os.popen(cmd)

        lines =stream.readlines();

        list =map(string.strip,lines)

        returnlist

 

inputarg = sys.argv

if len(inputarg) < 2:

    print'Please input panic log'

    exit()

 

filename = inputarg[1]

readlog = ReadLog(filename)

inputlist = readlog.parse()

 

for item in inputlist:

    itemsplit =item.split()

    test =ParseContent(itemsplit[-2],itemsplit[-1])

    list =test.addr2line()

    print"%-30s%s" % (list[1],list[0])

 

相關文章