为了更好地解析崩溃信息,快速准确地定位用户App发生崩溃的具体代码位置,需要上传对应版本的符号表到透视宝云端,对App发生崩溃的程序堆栈进行解析和反编译,从而还原崩溃堆栈。
上传iOS应用符号表
方法一:手动上传符号表
方法二:自动上传符号表
上传Android应用符号表
方法一:手动上传符号表
方法二:自动上传符号表
上传iOS应用符号表
方法一:手动上传符号表
要上传符号表,首先您需要在应用工程中找到对应的文件,对于iOS应用,符号表是指应用工程的dYSM文件([Appname].app.dYSM文件)。
步骤一:找到符号表
1. 打开应用工程,在工具栏中点击工程名称并选择“Edit Scheme”,如下图所示。

2. 在打开的对话框中,将工程由Debug模式转为Release模式后关闭对话框,如下图所示。

3. 编译工程,使用Command + B快捷键build工程。
4. 编译成功后,在应用工程的Products目录下,右击[Appname].app文件并选择“Show in Finder”,如下图所示。

5. 在打开的对话框中可以看到[Appname].app.dSYM文件,该文件即为用于解析崩溃信息的符号表,您可以在透视宝云端上传该文件。

需说明的是,当您的Archive模式为Build时,需要通过以下方式找到生成的dSYM文件:
1) 选择“Window→Organizer”,打开应用工程的Archive列表,如下图所示。

2) 选择您的App,右击Archive文件并选择“Show in Finder”,如下图所示。
\
3) 在打开的对话框中,右击[Appname time].xcarchive文件并选择“显示包内容”,如下图所示。

4) 在打开的对话框中,进入dSYM目录可以找到[Appname].app.dSYM文件,该文件即为用于解析崩溃信息的符号表,您可以在透视宝云端上传该文件。

步骤二:上传符号表
1) 生成符号表(dYSM文件)后,使用管理员角色的账户登录透视宝,在移动应用的设置>符号表页面上传符号列表,如下图所示。

2) 要上传符号表,首先需新建应用版本。点击<新建符号表>按钮新建一个应用版本,选择应用的类型并设置应用版本号,保存后可上传符号表。

3) 点击<上传>按钮上传应用对应版本的符号表,上传成功后其状态显示为“已上传”。

点击<删除>按钮可删除对应的应用版本及符号表。
方法二:自动上传符号表
除手动上传符号表, iOS应用还支持自动上传dSYM文件至云智慧服务平台,详细说明如下。
在XCode中找到App工程的Target,选择“Build Phase”,点击 “+ ”,添加一个新的Run Script Phase,如下图所示。

1. 添加shell脚本。
将下方的Shell脚本全部拷贝到新添加的Run Script Phase中。
#!/bin/sh
#手动配置项
#APP_KEY
APP_KEY="app_key here"
#BUNDLE_IDENTIFIER
BUNDLE_IDENTIFIER="Bundle Identifier"
#Debug模式编译是否上传dSYM文件,设置1为上传,设置0为不上传,默认不上传。建议只在测试该脚本功能的情况下才设置为1.
#!!!模拟器运行模式,不上传dSYM文件
#UPLOAD_DEBUG_MODEL=0
#
#以Archive打包操作时上传dSYM文件,设置1为只在以Archive打包方式才上传,以上UPLOAD_DEBUG_MODEL设置将失效
#设置0为所有打包模式都上传。建议将此参数设置为1.
UPLOAD_ARCHIVE_MODEL=1
#
#dSYM文件上传服务域名
DSYM_UPLOAD_DOMAIN="portal-qa-d.toushibao.com"
# 提示日志并退出
function MessageWhileExit(){
echo "[Cloudwise] ${1}"
exit 0
}
#上传应用dSYM文件
function uploaddSYM() {
U_APP_KEY="$1"
U_APP_BUNDLE_ID="$2"
U_APP_VERSION="$3"
U_APP_BUILD_VERSION="$4"
U_APP_DSYM_ZIP_FILE="$5"
U_APP_DSYM_ZIP_FILE_NAME=${U_APP_DSYM_ZIP_FILE##*/}
U_APP_DSYM_UPLOAD_URL="http://${DSYM_UPLOAD_DOMAIN}/mobile/api/SDKAutoAddDictionary"
echo "[Cloudwise] dSYM upload url: ${U_APP_DSYM_UPLOAD_URL},uploading..."
/usr/bin/curl -k "${U_APP_DSYM_UPLOAD_URL}" --form "app_key=${U_APP_KEY}" --form "bundle_id=${U_APP_BUNDLE_ID}" --form "os=ios" --form "app_version=${U_APP_VERSION}" --form "app_build_version=${U_APP_BUILD_VERSION}" --form "file_name=${U_APP_DSYM_ZIP_FILE_NAME}" --form "file=@${U_APP_DSYM_ZIP_FILE}"
echo "[Cloudwise] dSYM file upload complete."
}
#打包dSYM文件,组装参数
function beforUpload() {
B_APP_KEY="$1"
B_APP_BUNDLE_IDENTIFIER="$2"
B_APP_VERSION="$3"
B_APP_BUILD_VERSION="$4"
B_DSYM_SOURCE_DIR="$5"
B_DSYM_DEST_DIR="$6"
if [ ! -e "${B_DSYM_DEST_DIR}" ]; then
mkdir ${B_DSYM_DEST_DIR}
fi
echo "[Cloudwise] Scaning dSYM dir: ${B_DSYM_SOURCE_DIR} ..."
SEARCH_DSYM_FILE_RESULT="N"
for dSYMFile in $(find "$B_DSYM_SOURCE_DIR" -name '*.dSYM'); do
SEARCH_DSYM_FILE_RESULT="Y"
DSYM_FILE_NAME=${dSYMFile##*/}
DSYM_SYMBOL_ZIP_FILE_NAME="${DSYM_FILE_NAME}.zip"
DSYM_SYMBOL_ZIP_FILE="${B_DSYM_DEST_DIR}"/"${DSYM_SYMBOL_ZIP_FILE_NAME}"
if [ -e "${DSYM_SYMBOL_ZIP_FILE}" ]; then
rm -f "${DSYM_SYMBOL_ZIP_FILE}"
fi
zip -r -j "${DSYM_SYMBOL_ZIP_FILE}" "${dSYMFile}" -x *.plist
uploaddSYM "${B_APP_KEY}" "${B_APP_BUNDLE_IDENTIFIER}" "${B_APP_VERSION}" "${B_APP_BUILD_VERSION}" "${DSYM_SYMBOL_ZIP_FILE}"
done
if [ $SEARCH_DSYM_FILE_RESULT = "N" ]; then
MessageWhileExit "Not found .dSYM in ${B_DSYM_SOURCE_DIR}"
fi
}
#在Xcode中获取必要参数
function uploaddSYMInXcode(){
sleep 3s
BUNDLE_APP_VERSION=$(/usr/libexec/PlistBuddy -c 'Print CFBundleShortVersionString' "${INFOPLIST_FILE}")
THE_BUILD_VERSION=$(/usr/libexec/PlistBuddy -c 'Print CFBundleVersion' "${INFOPLIST_FILE}")
if [ ! "${THE_BUILD_VERSION}" ]; then
BUILD_VERSION="${THE_BUILD_VERSION}"
else
BUILD_VERSION=""
fi
#检查Debug模式编译时是否允许上传dSYM -- 测试用
if [ "${CONFIGURATION}" == "Debug" ]; then
if [ $UPLOAD_DEBUG_MODEL -eq 0 ]; then
MessageWhileExit "Skipping debug build model upload dSYM file"
elif [ "$EFFECTIVE_PLATFORM_NAME" == "-iphonesimulator" ]; then
MessageWhileExit "Skipping simulator build model upload dSYM file"
fi
fi
#检查是否Archive操作 -- release用
if [ $UPLOAD_ARCHIVE_MODEL -eq 1 ]; then
if [[ "$TARGET_BUILD_DIR" == *"/Archive"* ]]; then
echo "Archive the package"
else
MessageWhileExit "Skipping upload dSYM file"
fi
fi
#检查必要参数是否设置
if [ ! "${APP_KEY}" ]; then
MessageWhileExit "Error: App Key not defined."
fi
if [ ! "${BUNDLE_IDENTIFIER}" ]; then
MessageWhileExit "Error: Bundle Identifier not defined."
fi
beforUpload "${APP_KEY}" "${BUNDLE_IDENTIFIER}" "${BUNDLE_APP_VERSION}" "${BUILD_VERSION}" "${DWARF_DSYM_FOLDER_PATH}" "${BUILD_DIR}/CWdSYMTemp"
}
uploaddSYMInXcode2. 手动配置Shell脚本变量。
拷贝完成后需手动配置shell脚本变量,配置内容如下:
n APP_KEY:创建应用时自动生成,可从云智慧平台中获取。
n BUNDLE_IDENTIFIER:从工程targets中的Bundle identifier中获取,如下图所示。

n DSYM_UPLOAD_DOMAIN:配置dSYM文件上传服务域名为私有平台IP或域名。
n UPLOAD_DEBUG_MODEL:配置是否在debug模式自动上传dSYM文件。0为不上传,1为上传。默认不上传,编译对象为模拟器时不上传。
n UPLOAD_ARCHIVE_MODEL:配置是否只在Archive打包模式下自动上传dSYM文件。0为Debug打包和Archive打包都上传,1为只在Archive打包时上传,这时UPLOAD_DEBUG_MODEL配置失效。
注意事项:
n Debug打包模式生成的应用安装包里包含了符号表信息,建议只在测试自动上传脚本的情形下才开启Debug自动上传功能。
n 如果开启了Bitcode打包选项,并在上传时勾选了“Upload your app’s symbols to receive symbolicated reports from Apple”,这时就不需要再配置自动上传dSYM的脚本了。需要从App Store下载该版本应用对应的dSYM文件,然后从云智慧平台手动上传。
上传Android应用符号表
手动上传符号表
1. 要上传符号表,首先您需要在应用工程中找到对应的文件。对于Android应用,解码不同类型的崩溃信息,需要上传不同的崩溃解码文件。
n 解码Java Crash:如果要解码Java类型的崩溃信息(Java Crash),需要上传应用工程的mapping文件,找到该文件的详细说明见解码Java Crash。
n 解码Native Crash:如果要解码Native类型的崩溃信息(Native Crash),需要上传应用工程的Debug so文件,找到该文件的详细说明见解码Native Crash。
2. 找到对应的崩溃解码文件之后,使用管理员角色的账户登录透视宝,在移动应用的设置>上传符号表页面上传符号列表,如下图所示。

3. 要上传符号表,首先需新建应用版本。单击新建符号表新建一个应用版本,选择应用的类型并设置应用版本号,保存后可上传符号表。

4. 单击确定上传应用对应版本的符号表,上传成功后其状态显示为“已上传”。
单击删除,可删除对应的应用版本及符号表。
解码Java Crash
如果要解码Java类型的崩溃信息(Java Crash),只需要上传应用工程的mapping文件。以Android Studio开发环境为例进行说明:
在应用工程根目录的app/build/outputs/mapping/release/目录中找到mapping.txt文件,该文件即为用于解析崩溃信息的符号表,您可以在透视宝云端上传该文件。注意,proguard文件夹是为工程设置混淆后自动生成的。

解码Native Crash
如果要解码Native类型的崩溃信息(Native Crash),还需要上传应用工程的Debug so文件。
注意:您必须提前在应用工程中集成透视宝提供的Cloudwise NDK,编译应用工程后将对应的Debug so文件打包为zip包进行上传。
在Eclipse开发环境中
默认情况下,Debug SO文件是位于应用工程的obj/local/CPU架构目录下的libCreateNativeCrash.so文件,如下图所示。

上传前,需删除local目录中无关的文件夹和文件,只保留CPU架构目录和对应的Debug SO文件(libCreateNativeCrash.so),然后打包为zip包(local.zip),zip包的目录结构为<local-架构-Debug SO文件>,如下图所示。

您可以在透视宝云端上传该zip包,用于解析和还原崩溃信息。
为保证正常解析和还原崩溃信息,上传zip包的目录结构必须与要求的完全一致。当然,您可以根据自己的需要上传某一个架构的Debug SO文件(libCreateNativeCrash.so),只要确保目录结构一致即可。
在Android Studio开发环境中
默认情况下,Debug SO文件是位于应用工程的obj/local/CPU架构目录下的libCreateNativeCrash.so文件,如下图所示。

n 如果是Debug编译,默认情况下,Debug SO文件的具体的路径为:
<子项目文件夹>/build/intermediates/ndk/debug/obj/local/<架构(Architecture)>/
n 如果是Release编译,Debug SO文件的具体的路径为:
<子项目文件夹>/build/intermediates/ndk/release/obj/local/<架构(Architecture)>/
说明:Android Sutdio中"子项目"即Module,如app。
上传前,需删除local目录中无关的文件夹和文件,只保留CPU架构目录和对应的Debug SO文件(libCreateNativeCrash.so),然后打包为zip包(local.zip),zip包的目录结构为<local-架构-Debug SO文件>,如下图所示。

您可以在透视宝平台上传该zip包,用于解析和还原崩溃信息。
为保证正常解析和还原崩溃信息,上传zip包的目录结构必须与要求的完全一致。当然,您可以根据自己的需要上传某一个架构的Debug SO文件(libCreateNativeCrash.so),只要确保目录结构一致即可。
自动上传符号表
除手动上传符号表,Android应用还支持通过配置cloudwise-mobile.xml文件自动上传符号表至云智慧服务平台,详细说明如下。
在cloudwise-mobile.xml文件中添加配置项autoUpload,如下图所示。

autoUpload是控制是否自动上传符号表的开关,支持的符号表包括混淆符号表(mapping.txt)和NDK的SO文件。
autoUpload控制开关只有在开启了混淆或集成了透视宝NDK监控时才会生效。
n 如果项目使用了代码混淆(Proguard),透视宝SDK将自动上传Proguard生成的mapping.txt文件。
n 如果项目中使用了SO库,且嵌入了透视宝NDK监控。透视宝SDK将自动扫描SO文件,生成NDK符号表文件(工程根目录/cloudwise/local.zip),并自动上传。
n 如果项目没使用SO库或没有嵌入透视宝NDK监控,透视宝SDK将不会执行NDK符号表文件上传。
