介紹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。
文檔內容是否對您有幫助?