Remote desymbolication of iOS crash logs from Unreal Engine 4 games
Let's get straight to the point. You are developing an iOS game with Unreal Engine 4. Let's assume you are using a remote Mac machine to build the game (just like in this post). And the game crashes for unknown reasons. How to deal with it?
Enabling dSYM generation
First of all, UE4 must know if it want to generate dSYM files (which are used for desymbolicating crashlogs). To enable this option modify an DefaultEngine.ini file:
[/Script/IOSRuntimeSettings.IOSRuntimeSettings]
bGeneratedSYMFile=True
Have in mind that build time and build size may increase when this option is set to True.Extracting crash log
To get a crashlog from device on Windows I'm using a set of tool called iOSLogInfo. You can download it from here:
https://www.blackberry.com/blackberrytraining/web/KB_Resources/KB36986_iOSLogInfo_4.3.4.zip
Using console command run:
sdsioscrashlog.exe CrashLogs
It will download all of the crashlogs from the device and put them into a CrashLogs directory.
When you find your crashlog (it should have *.ips file extension) you will notice that it is not symbolicated. This file in it's current state won't get any useful information.
Thread 9 Crashed:
0 libsystem_kernel.dylib 0x00000001addafec4 0x1add8b000 + 151236
1 libsystem_pthread.dylib 0x00000001adccb774 0x1adcc9000 + 10100
2 libsystem_c.dylib 0x00000001adc1f844 0x1adbac000 + 473156
3 TestProject 0x0000000101675d18 0x1009c4000 + 13311256
4 TestProject 0x0000000101758ac0 0x1009c4000 + 14240448
5 TestProject 0x00000001017ef33c 0x1009c4000 + 14857020
6 TestProject 0x00000001017a4e84 0x1009c4000 + 14552708
7 TestProject 0x00000001017a4d30 0x1009c4000 + 14552368
8 TestProject 0x000000010152cea4 0x1009c4000 + 11964068
...
Sending crash log to remote machine
Crashlog can be desymbolicated on the machine it's been built on. To send it there you can use a pscp tool (to be downloaded from here: https://the.earth.li/~sgtatham/putty/latest/w64/pscp.exe)pscp.exe -P [port] -pw [password] [path_to_ips_file] [username]@[address]:/Users/[username]/UE4/Builds/[machine_name]/[project_path]/Binaries/IOS
where username, password, address and port are the parameters of the remote Mac machine the game was built on.Desymbolicating crash log
It's time for the main event - desymbolicating. Connect to your remote Mac machine via ssh (Putty is a great tool for this task, to be downloaded from here: https://the.earth.li/~sgtatham/putty/latest/w64/putty.exe).Go to your project's directory
cd /Users/[username]/UE4/Builds/[machine_name]/[project_path]/Binaries/IOS
here you should be able to locate dSYM and ips files. The symbolicatecrash tool will be used, which is a part of xcode. To make your work easier let's create an alias for it:
alias symbolicatecrash='/Applications/Xcode.app/Contents/SharedFrameworks/DVTFoundation.framework/Versions/A/Resources/symbolicatecrash'
(have in mind that this path is valid for xcode 8 and newer only). Before it can be used an environment variable must be set:
export DEVELOPER_DIR=$(xcode-select --print-path)
After all of that everything is ready to desymbolicate!symbolicatecrash -v MyCrashLog.ips TestProject.dSYM > Crashlog.txt
This will desymbolicate the MyCrashLog.ips file and will save results into the Crashlog.txt file.Downloading desymbolicating crash log back to local machine
To download txt file with desymbolicated crash let's just use pscp tool once again on Windows machine:pscp.exe -P [port] -pw [password] [username]@[address]:/Users/[username]/UE4/Builds/[machine_name]/[project_path]/Binaries/IOS/Crashlog.txt [download_path]
Now, when the desymbolicated crashlog is downloaded it can finally shows what was going on all the time:Thread 9 Crashed:
0 libsystem_kernel.dylib 0x00000001addafec4 0x1add8b000 + 151236
1 libsystem_pthread.dylib 0x00000001adccb774 0x1adcc9000 + 10100
2 libsystem_c.dylib 0x00000001adc1f844 0x1adbac000 + 473156
3 TestProject 0x0000000101675d18 FGenericPlatformMallocCrash::InitializeSmallPools() + 13311256 (GenericPlatformMallocCrash.cpp:468)
4 TestProject 0x0000000101758ac0 FIOSErrorOutputDevice::Serialize(char16_t const*, ELogVerbosity::Type, FName const&) + 14240448 (IOSErrorOutputDevice.cpp:0)
5 TestProject 0x00000001017ef33c FOutputDevice::LogfImpl(char16_t const*, ...) + 14857020 (OutputDevice.cpp:71)
6 TestProject 0x00000001017a4e84 AssertFailedImplV(char const*, char const*, int, char16_t const*, char*) + 14552708 (AssertionMacros.cpp:105)
7 TestProject 0x00000001017a4d30 FDebug::CheckVerifyFailedImpl(char const*, char const*, int, char16_t const*, ...) + 14552368 (AssertionMacros.cpp:0)
8 TestProject 0x000000010152cea4 UMyGameplayStatics::LeCrash() + 11964068 (MyGameplayStatics.cpp:117)
...