CrashLog与dSYM二三事
1、基础知识:
1)关于三个地址:stack address、slide、load address
slide:比较好理解,可以理解为虚拟的起始装入地址,可以使用下面的命令:
otool -arch armv7 -l ./Products/Applications/sinavideo.app/sinavideo
寻找里面的_TEXT段里面的vmaddr来得到
otool -arch armv7 -l ./Products/Applications/sinavideo.app/sinavideo|grep -B 3 -A 8 -m 2 "__TEXT"|grep vmaddr|awk '{print $2}'
0x00004000
stack address:实际运行的物理堆栈地址,也就是代码运行在目标机器时候,由OS来调用的地址,一般每次运行时候都会变化
这个可以从CrashLog中得到,即
0 Demo 0x000a82a6 0x7c000 + 180902 1 Demo 0x000b5bf8 0x7c000 + 236536 2 Demo 0x000b5a3a 0x7c000 + 236090
中的0x000a82a6地址,即为stack address,为实际运行的物理栈地址
load address:实际运行的main函数装入地址,这个与slide对应,只不过,load address为实际的装入地址,而slide为dSYM文件生成时候,使用的虚拟地址
如何得到load address,参照上面的例子,load address=stack address-实际偏移地址,即:load address=0x000a82a6(16)-180902(10)=507904(10)=0x7C000
2)第四个地址,关于symbol address,根据苹果文档,symbol address的含义为当前的偏移地址在dSYM文件中的对应值,公式:symbol address=slide+stack address-load address,以上面的例子说明:
symbol address=0x4000(slide)+0x000a82a6(stack address)-0x7C000(load address)
可以简化为:symbol address=0x4000(slide)+180902(10)=0x302A6(16),这个就是symbol address
3)关于arch,现在编译的sinavideo一共有两个arch,armv7、armv7s,分界点在iphone4s,晚于iphone4s的机型,使用armv7s,早于以及等于iphone4s的机型,使用armv7
2、用途:
可以使用dwarfdump或者atos等命令从symbol address来得到具体对应的代码语句,使用范例:
dwarfdump --lookup 0x436BA --arch armv7 sinavideo.app.dSYM
其中:0x436BA为symbol address,sinavideo.app.dSYM为发布时候得到的symbol文件,armv7为芯片集
3、整理的一个脚本 read_dsym.sh
具体用法:
1)将read_dsym.sh下载到本机,加入执行权限:chmod +x read_dsym.sh,建议将脚本放入固定路径,并且将此路径加入~/.bash_profile中,以保证在任意目录中都可以使用,比如:我的路径~/script,打开~/.bash_profile,将~/script路径加入PATH环境变量:
cat ~/.bash_profile
PATH=$PATH:~/script
export PATH
2)进入svn中存放dSYM的目录:
cd ~/myworks/ios/release//sinavideo/2.0.0/sinavideo\ 14-4-25\ 上午11.28.xcarchive
4 sinavideo 0x001cd1df _ZN15CTXAppidConvert10IsMQQAppIdEPKc + 259770
5 sinavideo 0x001c7525 _ZN15CTXAppidConvert10IsMQQAppIdEPKc + 236032
6 sinavideo 0x001c786b _ZN15CTXAppidConvert10IsMQQAppIdEPKc + 236870
7 sinavideo 0x001c591f _ZN15CTXAppidConvert10IsMQQAppIdEPKc + 228858
8 sinavideo 0x001c5335 _ZN15CTXAppidConvert10IsMQQAppIdEPKc + 227344
4)找到需要查找的地址,比如:259770,使用命令:
read_dsym.sh armv7 259770
查找相应的代码句子。
#!/bin/sh
toHex()
{
str=$1
sub_str=`echo ${str}|awk '{print substr($0,1,2)}'`
if [ $sub_str != "0x" ]; then
str=`echo ${str}|sed s/0x//g`
echo "ibase=10;obase=16;$str"|bc
return
fi
echo ${str}|sed s/0x//g
}
hexAdd()
{
str1=$1
str2=$2
str1=`echo ${str1}|sed s/0x//g|tr '[a-z]' '[A-Z]'`
str2=`echo ${str2}|sed s/0x//g|tr '[a-z]' '[A-Z]'`
ret=`echo "ibase=obase=16;${str1} + ${str2}"|bc`
echo "0x"${ret}
}
help()
{
echo "in your dsym directory,and press under it:"
echo "usage:read.sh [arch] [stack address]"
echo "sample:read.sh armv7 19352"
exit
}
if [ $# != 2 ]; then
help
fi
if [ $1 == "--help" ]; then
help
fi
ARCH=$1
CODE=$2
if [ $ARCH != "armv7" -a $ARCH != "armv7s" -a $ARCH != "armv6" ]; then
echo "arch is error,must be armv7s/armv7/armv6"
help
exit
fi
#APPPATH=`find . -name "*.app"`
#APPNAME=`echo $APPPATH|awk -F'/' '{print $2}'|sed s/\.app//g`
#APP=`echo $APPPATH|awk '{print $0"/"app_name}' app_name=${APPNAME}`
APPNAME="sinavideo"
APP="./Products/Applications/${APPNAME}.app"
CODE=`toHex $CODE`
cd $APP
SLIDE=`otool -arch ${ARCH} -l ./"$APPNAME"| grep -B 3 -A 8 -m 2 "__TEXT"|grep vmaddr|awk '{print $2}'`
SLIDE=`toHex $SLIDE`
SYMBOLADDR=`hexAdd $CODE $SLIDE`
cd -
cd "./dSYMs"
echo "dwarfdump --lookup ${SYMBOLADDR} --arch ${ARCH} ${APPNAME}.app.dSYM"|sh