为了更好地解析崩溃信息,快速准确地定位用户App发生崩溃的具体代码位置,需要上传对应版本的符号表到透视宝云端,对App发生崩溃的程序堆栈进行解析和反编译,从而还原崩溃堆栈。


上传iOS应用符号表

方法一:手动上传符号表

方法二:自动上传符号表

上传Android应用符号表

方法一:手动上传符号表

方法二:自动上传符号表



上传iOS应用符号表

方法一:手动上传符号表

要上传符号表,首先您需要在应用工程中找到对应的文件,对于iOS应用,符号表是指应用工程的dYSM文件([Appname].app.dYSM文件)。

 步骤一:找到符号表

1.      打开应用工程,在工具栏中点击工程名称并选择“Edit Scheme”,如下图所示。

1658369659838764.png

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

1658369782107773.png

3.      编译工程,使用Command + B快捷键build工程。

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

1658369825532880.png

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

1658369856347732.png

需说明的是,当您的Archive模式为Build时,需要通过以下方式找到生成的dSYM文件:

1)      选择“Window→Organizer”,打开应用工程的Archive列表,如下图所示。

1658369880552856.png

2)      选择您的App,右击Archive文件并选择“Show in Finder”,如下图所示。

\1658369916829350.png

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

1658369931319145.png

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

image113.png

步骤二:上传符号表

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

1658383787664839.png

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

1658383959783663.png

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


1658384107580044.png

点击<删除>按钮可删除对应的应用版本及符号表。


方法二:自动上传符号表

除手动上传符号表, iOS应用还支持自动上传dSYM文件至云智慧服务平台,详细说明如下。

在XCode中找到App工程的Target,选择“Build Phase”,点击 “+ ”,添加一个新的Run Script Phase,如下图所示。

1658384972842613.png

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"
}
 
uploaddSYMInXcode

2.      手动配置Shell脚本变量

拷贝完成后需手动配置shell脚本变量,配置内容如下:

n   APP_KEY:创建应用时自动生成,可从云智慧平台中获取。

n   BUNDLE_IDENTIFIER:从工程targets中的Bundle identifier中获取,如下图所示。

image121.png

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.      找到对应的崩溃解码文件之后,使用管理员角色的账户登录透视宝,在移动应用的设置>上传符号表页面上传符号列表,如下图所示。

1658371420643645.jpg

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

1658371430917980.jpg

4.      单击确定上传应用对应版本的符号表,上传成功后其状态显示为“已上传”。

单击删除,可删除对应的应用版本及符号表。


解码Java Crash

如果要解码Java类型的崩溃信息(Java Crash),只需要上传应用工程的mapping文件。以Android Studio开发环境为例进行说明:

在应用工程根目录的app/build/outputs/mapping/release/目录中找到mapping.txt文件,该文件即为用于解析崩溃信息的符号表,您可以在透视宝云端上传该文件。注意,proguard文件夹是为工程设置混淆后自动生成的。

image128.png


解码Native Crash

如果要解码Native类型的崩溃信息(Native Crash),还需要上传应用工程的Debug so文件。

注意:您必须提前在应用工程中集成透视宝提供的Cloudwise NDK,编译应用工程后将对应的Debug so文件打包为zip包进行上传。

在Eclipse开发环境中

默认情况下,Debug SO文件是位于应用工程的obj/local/CPU架构目录下的libCreateNativeCrash.so文件,如下图所示。

image129.png

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

image131.png

您可以在透视宝云端上传该zip包,用于解析和还原崩溃信息。

为保证正常解析和还原崩溃信息,上传zip包的目录结构必须与要求的完全一致。当然,您可以根据自己的需要上传某一个架构的Debug SO文件(libCreateNativeCrash.so),只要确保目录结构一致即可。

在Android Studio开发环境中

默认情况下,Debug SO文件是位于应用工程的obj/local/CPU架构目录下的libCreateNativeCrash.so文件,如下图所示。

1658372364937791.png

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文件>,如下图所示。

image131.png

您可以在透视宝平台上传该zip包,用于解析和还原崩溃信息。

为保证正常解析和还原崩溃信息,上传zip包的目录结构必须与要求的完全一致。当然,您可以根据自己的需要上传某一个架构的Debug SO文件(libCreateNativeCrash.so),只要确保目录结构一致即可。

自动上传符号表

除手动上传符号表,Android应用还支持通过配置cloudwise-mobile.xml文件自动上传符号表至云智慧服务平台,详细说明如下。

在cloudwise-mobile.xml文件中添加配置项autoUpload,如下图所示。

 1658372434641009.png

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符号表文件上传。