Android IL2cpp Crash堆栈还原
Android IL2cpp Crash堆栈还原
如何将内存地址转为可读的函数名
1
${addr2line.exe} -a -C -f -e "C:/Program Files/Unity/Hub/Editor/2018.4.0f1/Editor/Data/PlaybackEngines/AndroidPlayer/Variations/il2cpp/Development/Symbols/armeabi-v7a/libunity.sym.so" 0043a05c
Windows批处理
1
2
3
4
5
6
7
@ECHO OFF
SET Ad2LinePath="addr2line.exe"
SET LinInfo="lineinfo.txt"
ECHO "==============================="
"%Ad2LinePath%" @"%LinInfo%"
ECHO "==============================="
PAUSE
lineinfo.txt
1
-a -C -f -e "F:/WorkProject/_Develop/program/client/trunk/game/Prj-G/addr2lineTools/libil2cpp.sym" 01a23918 00f45b68 01c335f0 00488808 019df9ec
列出 .so 文件中的符号
nm
列出符号的标准工具是nm
,可以像这样简单地使用它:
1
nm -gD yourLib.so
如果想查看 C++ 库的符号,请添加“-C”选项来对符号进行分解(分解后的可读性更高)。
1
nm -gDC yourLib.so
如果你的 .so 文件是 elf 格式,你有两个选择:
objdump
要么objdump
(-C
对于分解 C++ 也很有用):
1
2
3
4
5
6
7
8
9
$ objdump -TC libz.so
libz.so: file format elf64-x86-64
DYNAMIC SYMBOL TABLE:
0000000000002010 l d .init 0000000000000000 .init
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 free
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 __errno_location
0000000000000000 w D *UND* 0000000000000000 _ITM_deregisterTMCloneTable
readelf
或使用readelf
:
1
2
3
4
5
6
7
8
$ readelf -Ws libz.so
Symbol table '.dynsym' contains 112 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000002010 0 SECTION LOCAL DEFAULT 10
2: 0000000000000000 0 FUNC GLOBAL DEFAULT UND free@GLIBC_2.2.5 (14)
3: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __errno_location@GLIBC_2.2.5 (14)
4: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_deregisterTMCloneTabl
问题
在libil2cpp.so上进行Android(IL2CPP)生产构建时,在发生的崩溃中表征一个调用堆栈,需要保存该库的符号表。
该符号文件每次在 <ProjectFolder>/Temp/ directory
下构建时被创建,当编辑器应用退出后被移除,所以可能看不到它们。
解决方案
每次构建后,可以从下述位置获得符号:
<ProjectFolder>\Temp\StagingArea\libs\x86\libil2cpp.so.debug
<ProjectFolder>\Temp\StagingArea\libs\armeabi-v7a\libil2cpp.so.debug
确保在关闭Unity编辑器之前将符号文件复制到不同的文件夹中。也可以使用下面的后期构建脚本:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
using UnityEngine;
using System.Collections;
using UnityEditor.Callbacks;
using UnityEditor;
using System.IO;
using System;
public class MyBuildPostprocessor
{
[PostProcessBuildAttribute()]
public static void OnPostprocessBuild(BuildTarget target, string pathToBuiltProject)
{
if (target == BuildTarget.Android)
PostProcessAndroidBuild(pathToBuiltProject);
}
public static void PostProcessAndroidBuild(string pathToBuiltProject)
{
UnityEditor.ScriptingImplementation backend = UnityEditor.PlayerSettings.GetScriptingBackend(UnityEditor.BuildTargetGroup.Android) as UnityEditor.ScriptingImplementation;
if (backend == UnityEditor.ScriptingImplementation.IL2CPP)
{
CopyAndroidIL2CPPSymbols(pathToBuiltProject, PlayerSettings.Android.targetDevice);
}
}
public static void CopyAndroidIL2CPPSymbols(string pathToBuiltProject, AndroidTargetDevice targetDevice)
{
string buildName = Path.GetFileNameWithoutExtension(pathToBuiltProject);
FileInfo fileInfo = new FileInfo(pathToBuiltProject);
string symbolsDir = fileInfo.Directory.Name;
symbolsDir = symbolsDir + "/"+buildName+"_IL2CPPSymbols";
CreateDir(symbolsDir);
switch (PlayerSettings.Android.targetDevice)
{
case AndroidTargetDevice.FAT:
{
CopyARMSymbols(symbolsDir);
CopyX86Symbols(symbolsDir);
break;
}
case AndroidTargetDevice.ARMv7:
{
CopyARMSymbols(symbolsDir);
break;
}
case AndroidTargetDevice.x86:
{
CopyX86Symbols(symbolsDir);
break;
}
default:
break;
}
}
const string libpath = "/../Temp/StagingArea/libs/";
Const string libFilename = "libil2cpp.so.debug";
private static void CopyARMSymbols(string symbolsDir)
{
string sourcefileARM = Application.dataPath + libpath + "armeabi-v7a/" + libFilename;
CreateDir(symbolsDir + "/armeabi-v7a/");
File.Copy(sourcefileARM, symbolsDir + "/armeabi-v7a/libil2cpp.so.debug");
}
private static void CopyX86Symbols(string symbolsDir)
{
string sourcefileX86 = Application.dataPath + libpath + "x86/libil2cpp.so.debug";
File.Copy(sourcefileX86, symbolsDir + "/x86/libil2cpp.so.debug");
}
public static void CreateDir(string path)
{
if (Directory.Exists(path))
return;
Directory.CreateDirectory(path);
}
}
本文由作者按照 CC BY 4.0 进行授权