一.分析材料
1.1 tombstone文件
位置:data/tombstones/中,最多存10個(gè),超過會(huì)從最舊的復(fù)寫掉.
chengang@mi:~/Documents/gdb_file$ adb shell
phoenix:/ # cd data/tombstones/
phoenix:/data/tombstones # ls -la
total 6155
drwxrwx--x 6 system system 3488 2019-12-25 17:14 .
drwxrwx--x 55 system system 4096 2019-12-25 15:27 ..
drwxrwx--x 2 system system 3488 1970-02-27 06:56 dsps
drwxrwx--x 2 system system 3488 1970-02-27 06:56 lpass
drwxrwx--x 2 system system 3488 1970-02-27 06:56 modem
-rw-r----- 1 tombstoned system 1103345 2019-12-25 14:52 tombstone_00
-rw-r----- 1 tombstoned system 1272737 2019-12-25 15:28 tombstone_01
-rw-r----- 1 tombstoned system 1434693 2019-12-25 15:29 tombstone_02
-rw-r----- 1 tombstoned system 1245462 2019-12-25 17:10 tombstone_03
-rw-r----- 1 tombstoned system 1211508 2019-12-25 17:14 tombstone_04
drwxrwx--x 2 system system 3488 1970-02-27 06:56 wcnss
tombstone信息:
日后詳細(xì)的tombstone文件分析將寫一篇,先在這立個(gè)flag
1.2 Symbol文件
GCC編譯加-g參數(shù)編譯器會(huì)在目標(biāo)文件中加上調(diào)試信息符號的行號信息等,android項(xiàng)目上在out/target/product/xxxx/symbol下對應(yīng)so的目錄下:
使用strip命令去除debug等無用信息,瘦身作用.
多出來的section即是debug信息部分,包含符號所在行數(shù).
看出symbol文件中有較多的debug section,掌握這些section的作用在分析問題時(shí)便可以獲得更多的debug信息.
1.3 coredump
文件作用:
當(dāng)進(jìn)程意外終止時(shí),系統(tǒng)可以將該進(jìn)程的地址空間的內(nèi)容及終止時(shí)的一些其他信息轉(zhuǎn)儲(chǔ)到coredump中,也是elf文件
可以使用GDB對進(jìn)程異常時(shí)的現(xiàn)場進(jìn)行調(diào)試查找問題.
抓取coredump的方法需要提前設(shè)置
coredump中提取oat文件的方法:https://www.cnblogs.com/YYPapa/p/6851259.html
二. 分析工具
2.1 addr2line
功能作用:用來分析單個(gè)pc地址對應(yīng)的源碼行數(shù)
工具位置:
chengang@mi:~$ which addr2line
/usr/bin/addr2line
使用方法:
chengang@mi:~$ addr2line -h
Usage: addr2line [option(s)] [addr(s)]
Convert addresses into line number/file name pairs.
If no addresses are specified on the command line, they will be read from stdin
The options are:
@<file> Read options from <file>
-a --addresses Show addresses
-b --target=<bfdname> Set the binary file format
-e --exe=<executable> Set the input file name (default is a.out)
-i --inlines Unwind inlined functions
-j --section=<name> Read section-relative offsets instead of addresses
-p --pretty-print Make the output easier to read for humans
-s --basenames Strip directory names
-f --functions Show function names
-C --demangle[=style] Demangle function names
-h --help Display this information
-v --version Display the program's version
addr2line: supported targets: elf64-x86-64 elf32-i386 elf32-iamcu elf32-x86-64 a.out-i386-linux pei-i386 pei-x86-64 elf64-l1om elf64-k1om elf64-little elf64-big elf32-little elf32-big pe-x86-64 pe-bigobj-x86-64 pe-i386 plugin srec symbolsrec verilog tekhex binary ihex
Report bugs to <http://www.sourceware.org/bugzilla/>
使用舉例:
注意如果有inline的函數(shù),添加-i參數(shù)
2.2 ndk-stack
工具位置:在Sdk的ndk目錄下,如果沒有ndk目錄,可以使用Sdk-manager下載Sdk-tool中的NDK support工具,即有ndk-stack腳本工具
chengang@mi:~/Android/Sdk$ find . -iname "ndk-stack"
./ndk/20.1.5948944/ndk-stack
./ndk/20.1.5948944/prebuilt/linux-x86_64/bin/ndk-stack
使用方法:
chengang@mi:~/Android/Sdk/ndk/20.1.5948944$ ./ndk-stack -h
usage: ndk-stack.py [-h] -sym SYMBOL_DIR [-i INPUT]
Symbolizes Android crashes.
optional arguments:
-h, --help show this help message and exit
-sym SYMBOL_DIR, --sym SYMBOL_DIR
directory containing unstripped .so files
-i INPUT, -dump INPUT, --dump INPUT
input filename
See <https://developer.android.com/ndk/guides/ndk-stack>.
使用舉例:
當(dāng)然也可以使用自己寫的腳本,實(shí)現(xiàn)原理基本都是批量addr2line
https://blog.csdn.net/TaylorPotter/article/details/86522986
2.3 c++filt
功能作用:
對于被編譯器轉(zhuǎn)換過的函數(shù)名,可以通過c++filt工具查看原始函數(shù)
函數(shù)簽名:所有的符號都以"_Z"開頭,對于嵌套的名字(在命名空間或類里面的),后面緊跟"N",然后是各個(gè)名稱空間和類的名字,每個(gè)名字前是名字字符串長度,再以E結(jié)尾,對于一個(gè)函數(shù)來說,他的參數(shù)列表緊跟在"E"后面,對于int即"i",void即"v"
工具位置:
chengang@mi:~/miui/miui_code/g7b_q_dev_11_20/prebuilts$ which c++filt
/usr/bin/c++filt
使用方法:
chengang@mi:~$ c++filt -h
Usage: c++filt [options] [mangled names]
Options are:
[-_|--strip-underscore] Ignore first leading underscore
[-n|--no-strip-underscore] Do not ignore a leading underscore (default)
[-p|--no-params] Do not display function arguments
[-i|--no-verbose] Do not show implementation details (if any)
[-t|--types] Also attempt to demangle type encodings
[-s|--format {none,auto,gnu,lucid,arm,hp,edg,gnu-v3,java,gnat,dlang}]
[@<file>] Read extra options from <file>
[-h|--help] Display this information
[-v|--version] Show the version information
Demangled names are displayed to stdout.
If a name cannot be demangled it is just echoed to stdout.
If no names are provided on the command line, stdin is read.
Report bugs to <http://www.sourceware.org/bugzilla/>.
使用舉例:
tombstone中的frame,方法名優(yōu)化過:
還原后:
2.4 Objdump
功能作用:用來把相應(yīng)的so變成匯編語言的asm文件
工具位置:
chengang@mi:~/miui/miui_code/g7b_q_dev_11_20/prebuilts$ find -iname Objdump
./gcc/linux-x86/aarch64/aarch64-linux-android-4.9/aarch64-linux-android/bin/objdump
./gcc/linux-x86/host/x86_64-w64-mingw32-4.8/x86_64-w64-mingw32/bin/objdump
./gcc/linux-x86/host/x86_64-linux-glibc2.17-4.8/x86_64-linux/bin/objdump
./gcc/linux-x86/x86/x86_64-linux-android-4.9/x86_64-linux-android/bin/objdump
./gcc/linux-x86/arm/arm-linux-androideabi-4.9/arm-linux-androideabi/bin/objdump
./gcc/linux-x86/arm/arm-eabi-4.8/arm-eabi/bin/objdump
./go/linux-x86/pkg/tool/linux_amd64/objdump
./go/linux-x86/src/cmd/objdump
./tools/gcc-sdk/objdump
使用方法:
chengang@mi:~/miui/miui_code/g7b_q_dev_11_20/prebuilts$ ./gcc/linux-x86/x86/x86_64-linux-android-4.9/x86_64-linux-android/bin/objdump --help
Usage: ./gcc/linux-x86/x86/x86_64-linux-android-4.9/x86_64-linux-android/bin/objdump <option(s)> <file(s)>
Display information from object <file(s)>.
At least one of the following switches must be given:
-a, --archive-headers Display archive header information
-f, --file-headers Display the contents of the overall file header
-p, --private-headers Display object format specific file header contents
-P, --private=OPT,OPT... Display object format specific contents
-h, --[section-]headers Display the contents of the section headers
-x, --all-headers Display the contents of all headers
-d, --disassemble Display assembler contents of executable sections
-D, --disassemble-all Display assembler contents of all sections
-S, --source Intermix source code with disassembly
-s, --full-contents Display the full contents of all sections requested
-g, --debugging Display debug information in object file
-e, --debugging-tags Display debug information using ctags style
......
舉例:
上面tombstone_04對應(yīng)的cam chi override 庫的objdump
2.5 IDA工具
https://blog.csdn.net/u012195899/article/details/52938353
2.6 Debuggerd
功能作用:查看目標(biāo)進(jìn)程的所有線程的當(dāng)前調(diào)用棧
工具位置:
chengang@mi:~/Documents/gdb_file$ adb shell
phoenix:/ # which debuggerd
/system/bin/debuggerd
phoenix:/ #
使用方法:
phoenix:/ # debuggerd -h
usage: debuggerd [-bj] PID
-b, --backtrace just a backtrace rather than a full tombstone
-j collect java traces
1|phoenix:/ #
chengang@mi:~/Documents/gdb_file$ adb shell ps -ef | grep camera
cameraserver 1042 1 0 14:51:52 ? 00:00:30 cameraserver
u0_a63 16781 661 0 15:56:27 ? 00:00:14 com.android.camera
cameraserver 24563 1 0 20:29:35 ? 00:00:01 android.hardware.camera.provider@2.4-service_64
chengang@mi:~/Documents/gdb_file$ adb shell debuggerd -b 24563 > camera.trace.txt
2.7 Oatdump
功能作用:解析oat文件
工具位置:
使用方法:
使用案例:
2.8 GDB
功能作用:暫停程序以調(diào)試程序
工具位置:
chengang@mi:~/miui/miui_code/g7b_q_dev_11_20/development/scripts$ ls -la | grep -i "gdbclient*"
-rwxrwxr-x 1 chengang chengang 6119 11月 20 21:21 gdbclient
-rwxrwxr-x 1 chengang chengang 14033 11月 20 21:21 gdbclient.py
使用方法:
chengang@mi:~/miui/miui_code/g7b_q_dev_11_20$ gdbclient.py --help
usage: gdbclient.py [-h] [--adb ADB_PATH] [-a | -d | -e | -s SERIAL]
(-p PID | -n NAME | -r ...) [--port [PORT]]
[--user [USER]] [--setup-forwarding {gdb,vscode}]
[--env VAR=VALUE]
optional arguments:
-h, --help show this help message and exit
--adb ADB_PATH use specific adb command
--port [PORT] override the port used on the host [default: 5039]
--user [USER] user to run commands as on the device [default: root]
--setup-forwarding {gdb,vscode}
Setup the gdbserver and port forwarding. Prints
commands or .vscode/launch.json configuration needed
to connect the debugging client to the server.
--env VAR=VALUE set environment variable when running a binary
device selection:
-a directs commands to all interfaces
-d directs commands to the only connected USB device
-e directs commands to the only connected emulator
-s SERIAL directs commands to device/emulator with the given
serial
attach target:
-p PID attach to a process with specified PID
-n NAME attach to a process with specified name
-r ... run a binary on the device, with args
使用案例:GDB常用命令
常用的功能有:
1.設(shè)置斷點(diǎn)(條件斷點(diǎn)),打印調(diào)用棧
2.查看各線程等信息
線程調(diào)用棧,切換到調(diào)用棧的第n層,附近代碼,匯編代碼查看,寄存器查看,變量查看(值或類型),查看內(nèi)存信息,查看變量偏移
3.單步調(diào)試
改變變量值
4.對coredump進(jìn)行分析調(diào)試:coredump分析實(shí)操
三.總結(jié)
屠龍寶刀很厲害,但還是需要一定的內(nèi)功才能發(fā)揮出寶刀的威力
需要一定的技術(shù)基礎(chǔ)總結(jié)如下:
技術(shù)基礎(chǔ) | 說明 | 參考 |
---|---|---|
操作系統(tǒng) | 進(jìn)程的調(diào)度,內(nèi)存分配的知識(shí),對理解程序運(yùn)行很有幫助 | |
ARM Architecture | 針對android操作系統(tǒng)指令運(yùn)行及問題分析幫助很大 | |
鏈接,裝載與庫 | 計(jì)算機(jī)程序運(yùn)行的基本原理,萬變不離其宗 | <程序員的自我修養(yǎng)> |
ELF spec | elf里面提供很多debug信息翘瓮,掌握可以方便使用arm-eabi-readelf來看這些debug信息 | |
coredump機(jī)制 | coredump是進(jìn)程出問題的現(xiàn)場,是對debug NE最有效的材料 | |
ptrace機(jī)制 | ptrace是用一個(gè)進(jìn)程debug另外一個(gè)進(jìn)程的機(jī)制贮折,這也是GDB的核心實(shí)現(xiàn)機(jī)制 | |
Linux的signal機(jī)制 | NE都會(huì)伴隨signal的發(fā)出 | |
業(yè)務(wù)邏輯 | 熟悉業(yè)務(wù)邏輯能更快的了解上下文以更快的分析場景和根本愿意 | |
線程安全 | 線程安全是一類很大幾率引起NE的因素 |