介绍Android符号表的基础概念,以及如何找到符号表并上传。
一、什么是符号表
在Android平台上,符号表用于将混淆过的代码进行还原,其中Java代码的符号化文件是mapping文件,C/C++代码的符号化文件是SO文件。
1. mapping文件
mapping文件可用于对混淆后的Java Crash堆栈进行还原。
原始堆栈
java.lang.NullPointerException at com.aliyun.emas.android.apm.CrashActivity$o.a(CrashActivity.java:1) at com.aliyun.emas.android.apm.CrashActivity$f.onClick(CrashActivity.java:1) at android.view.View.performClick(View.java:7751) at android.view.View.performClickInternal(View.java:7724) at android.view.View.access$3700(View.java:858) at android.view.View$PerformClick.run(View.java:29336) at android.os.Handler.handleCallback(Handler.java:938) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loopOnce(Looper.java:211) at android.os.Looper.loop(Looper.java:300) at android.app.ActivityThread.main(ActivityThread.java:8285) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:576) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1074)
还原堆栈
java.lang.NullPointerException at com.aliyun.emas.android.apm.CrashActivity$JavaCrash.throwException(CrashActivity.java:281) at com.aliyun.emas.android.apm.CrashActivity$1.onClick(CrashActivity.java:54) at android.view.View.performClick(View.java:7778) at android.view.View.performClickInternal(View.java:7755) at android.view.View.-$$Nest$mperformClickInternal(Unknown Source:0) at android.view.View$PerformClick.run(View.java:30769) at android.os.Handler.handleCallback(Handler.java:1013) at android.os.Handler.dispatchMessage(Handler.java:101) at android.os.Looper.loopOnce(Looper.java:226) at android.os.Looper.loop(Looper.java:328) at android.app.ActivityThread.main(ActivityThread.java:9179) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:594) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099) Back traces end.
2. SO符号表
SO符号表是用来存储源代码中符号信息的数据结构,符号表元素如下所示:
<起始地址> <结束地址> <函数> [<文件名:行号>]
SO符号表可用于对Native Crash堆栈进行还原。
原始堆栈
#00 pc 000000000000f224 /data/app/~~z7k3Yi_OI3CSgGIlRwLTAA==/com.aliyun.ha.test_8-kjF3YBAA72Ed6Q0gg9U7fQ==/lib/arm64/libnativecrash.so (_Z4testv+20) #01 pc 000000000000f200 /data/app/~~z7k3Yi_OI3CSgGIlRwLTAA==/com.aliyun.ha.test_8-kjF3YBAA72Ed6Q0gg9U7fQ==/lib/arm64/libnativecrash.so (Java_com_example_nativecrash_NativeLib_mockSigSegv+20) #02 pc 0000000000022244 /apex/com.android.art/lib64/libart.so (art_quick_generic_jni_trampoline+148) #03 pc 0000000000018964 /apex/com.android.art/lib64/libart.so (art_quick_invoke_stub+548) #04 pc 00000000000845a8 /apex/com.android.art/lib64/libart.so (_ZN3art9ArtMethod6InvokeEPNS_6ThreadEPjjPNS_6JValueEPKc+188) #05 pc 00000000001fd680 /apex/com.android.art/lib64/libart.so (_ZN3art11interpreter34ArtInterpreterToCompiledCodeBridgeEPNS_6ThreadEPNS_9ArtMethodEPNS_11ShadowFrameEtPNS_6JValueE+400) #06 pc 00000000001f84f4 /apex/com.android.art/lib64/libart.so (_ZN3art11interpreter6DoCallILb0ELb0EEEbPNS_9ArtMethodEPNS_6ThreadERNS_11ShadowFrameEPKNS_11InstructionEtPNS_6JValueE+804) #07 pc 0000000000595d50 /apex/com.android.art/lib64/libart.so (MterpInvokeVirtual+1168) #08 pc 0000000000003814 /apex/com.android.art/lib64/libart.so (mterp_op_invoke_virtual+20)
还原堆栈
#00 pc 0xf224 libnativecrash.so (/Users/liubaowen/projects/temp/emas-android-appmonitor-demo/nativecrash/src/main/cpp/nativecrash.cpptest() #01 pc 0xf200 libnativecrash.so (/Users/liubaowen/projects/temp/emas-android-appmonitor-demo/nativecrash/src/main/cpp/nativecrash.cppJava_com_example_nativecrash_NativeLib_mockSigSegv+line:17) #02 pc 0x22244 libart.so (art_quick_generic_jni_trampoline+148) #03 pc 0x18964 libart.so (art_quick_invoke_stub+548) #04 pc 0x845a8 libart.so (_ZN3art9ArtMethod6InvokeEPNS_6ThreadEPjjPNS_6JValueEPKc+188) #05 pc 0x1fd680 libart.so (_ZN3art11interpreter34ArtInterpreterToCompiledCodeBridgeEPNS_6ThreadEPNS_9ArtMethodEPNS_11ShadowFrameEtPNS_6JValueE+400) #06 pc 0x1f84f4 libart.so (_ZN3art11interpreter6DoCallILb0ELb0EEEbPNS_9ArtMethodEPNS_6ThreadERNS_11ShadowFrameEPKNS_11InstructionEtPNS_6JValueE+804) #07 pc 0x595d50 libart.so (MterpInvokeVirtual+1168) #08 pc 0x3814 libart.so (mterp_op_invoke_virtual+20)
二、如何找到符号表
1. mapping文件位置
如果在:<project>/<app-module>/build.gradle
中打开了混淆,则在编译完成后会生成mapping文件。
android {
...
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
...
}
默认情况下,mapping文件位置在<project>/<app-module>/build/outputs/mapping/<build-type>/
。
2. SO符号表位置
Android平台中,Debug SO文件是指具有调试信息的SO文件,其中包含用户还原堆栈的符号信息。
CMake编译项目
默认情况下,编译的SO文件在
<project>/<sdk-module>/build/intermediates/cmake/<build-type>/obj/CPU架构/
。NDK编译项目
默认情况下,编译的SO文件在
<project>/<sdk-module>/build/intermediates/ndk/<build-type>/obj/CPU架构/
。
三、如何上传符号表
详见 网页上传符号表。
四、FAQ
详见 符号表 FAQ。
文档内容是否对您有帮助?