[MUSIC PLAYING]
MARC RICHARDS: Hello, folks.
I'm Marc Richards, an Engineer on the Firebase Crashlytics
team.
And I'm excited to talk to you today
about the recent improvements to Crashlytics for Unity.
As a mobile game developer, debugging issues
like memory corruption or a missing GPU feature
can be complex and time consuming.
And a game that constantly glitches
can leave your players feeling frustrated and drive down
your app store rating.
In fact, quality issues are the most common reason
for early app deletion.
One in five users, 19%, will uninstall
an app due to technical errors or crashes.
And 54% of one-star app reviews mention app stability
as a concern.
That's why we've made a few updates to Crashlytics
to make it easier to improve your game stability.
Crashlytics is a crash reporting tool available for Unity
as part of the Firebase SDK for Unity.
It provides an intuitive web console,
so you can monitor your app stability,
understand your bugs, and prioritize what to fix.
If you're new to Crashlytics here's
a look at one of our console pages.
You see there's a number of graphs showing
the stability of your app and a list of all recent crashes
and errors sorted by frequency.
You can click into those issues and get full stack traces
for all similar crashes and see lots of other useful data
about the state of the app at the time of the error.
Crashlytics is widely used across the Android and iOS
ecosystems, including in lots of Unity games.
We've made three major Unity-specific improvements
in the past several months that we
feel makes Crashlytics the best option for crash reporting
for mobile games.
First, we brought great IL2CPP support to Crashlytics
to get more actionable stack traces in the dashboard.
Second, we've made big improvements
to issue prioritization.
So you can quickly identify, prioritize, and debug issues
in your game before they affect your users.
And lastly, we've added Unity-specific crash metadata
for those tricky problems where the stack trace doesn't
give you the whole picture.
I'm going to start off by introducing our new IL2CPP
support, and then hand it over to my colleague
Sam to cover the other two improvements we've made.
A few years back, Unity introduced
IL2CPP as an option for your game scripting backend.
It is now the default option, which
comes with performance benefits since it uses compiled
instead of interpreted code.
But for crash reporting, IL2CPP presented many challenges.
Let's dig into IL2CPP's compilation process to see why.
As the name suggests, IL2CPP transpiles your C# code
into C++ code.
So now, even though you wrote your game code in C#,
the app is actually executing code that was built from C++
source.
That source was automatically generated from your C# code.
That's the first step of the process.
On Android and iOS, this generated C++ code is directly
compiled on the respective platform using the iOS
and Android build tools.
So under the hood, your Unity app
is built using Gradle for Android and Xcode for iOS.
Again, your C# code is not compiled by these tools.
They compile the generated C++ code instead.
The result is that IL2CPP apps will
run native libraries on Android and iOS
rather than interpreted code.
In fact, when you export your Unity game to Xcode or Android
Studio, you can actually inspect the C++ source files that
the IL2CPP compiler generated.
If you had a raw stack trace from your Unity app,
you'd probably need to look at the C++ code to figure out what
part of your C# code caused the issue.
So with IL2CPP as our scripting back end,
let's talk about what the crash reporting experience was
like before we made improvements to support it.
Let's start with crash reporting on Android.
Looking back, Crashlytics for Unity
used to only include our standard Java-based
Crashlytics, Android SDK.
By default, Unity handles native crashes
by wrapping them in a Java exception.
The result is that Crashlytics has always
received IL2CPP crash reports because Crashlytics
can handle these Java objects.
This sounds great, but in practice,
the contents of the crash leave a lot of room for improvement.
Imagine your app crashed with the older version
of Crashlytics for Unity.
The stack trace in your Crashlytics console
might look like this.
It is a native exception represented
as a Java exception.
In a typical Java exception, the stack frame names
are the method names, which makes debugging quite simple.
However, because these are wrapped native crashes,
the stack frames are raw, unsymbolicated in memory
addresses.
Looking at the stack trays, figuring out
what part of your code caused this crash
would be really tricky.
Now, you might be able to make use of the memory addresses
with some hacking and manual pointer resolution.
But it isn't straightforward.
If you're like me and you prefer your stack traces have
actual simple names, I have great news for you.
The latest version of the Crashlytics SDK
for Unity on Android comes bundled with an upgraded NDK
crash reporter.
This brings lots of improvements for Android C++ crash reporting
to Unity for handling IL2CPP crashes.
Previously, integrating Crashlytics NDK crash reporting
into your Unity game wasn't officially supported,
and it required some clunky steps
to modify your exported Android Studio project.
Now, not only is Android NDK crash reporting supported,
it is part of the Crashlytics SDK for Unity by default. Also,
to get symbolicated stack traces Crashlytics servers need
symbol information from your native library.
That information is typically stripped from the binaries
before the app is compiled.
We've recently integrated Android native symbol uploads
into the Firebase CLI.
So now you have a convenient supported way
to upload these symbol files needed
to symbolicate your Android IL2CPP stack frames at build
time.
Even when Unity generates multiple symbol files,
uploading them to Crashlytics is just a command line call away.
And for developers who use native plugins in your game,
you can upload their symbols using the same tool.
The result?
Remember that stack trace of raw addresses we looked at before?
Here are much more helpful C++ stack traces from this updated
version of our SDK for Unity.
This is a huge improvement over Java-based crashes
as there are line numbers and actual method names.
Now, instead of needing to hand resolve a bunch of symbol
addresses to figure out what is in the stack trace,
you can directly see where each frame points to in the C++
source code.
But there's still one problem.
These frames correspond to the generated C++ code which you
didn't write.
So there's still some hurdles, making it difficult to find
the exact place in your C# code responsible for the issue.
We fixed that too, but we'll get to that in a moment.
First, now that I've showed you some Android improvements,
I also want to touch on similar improvements on the iOS side.
Crashlytics for Unity on iOS has always had native crash
reporting out of the box.
But often your stack traces would have missing frames,
as you can see here.
Again, we're seeing frames that lack meaningful symbol
information, which makes it difficult to pinpoint the root
cause of the issue in your app.
This occurs because Crashlytics doesn't have access
to Unity framework symbols.
But regardless of the reason, this
is a frustrating thing to see in the Crashlytics console.
Good news.
We've recently revamped the Crashlytics SDK for Unity
to automatically upload these symbols for iOS apps.
So you'll now see fully symbolicated frames,
as shown on the right.
So those are our IL2CPP specific improvements.
If you have never used Crashlytics before
or have relied on it heavily but been frustrated
by its limitations in IL2CPP apps,
you can see the benefits of these changes
right away by getting the latest version of Crashlytics today.
Now I'll hand it over to my colleague Sam
to cover the other two Unity-specific
improvements we've made to help you get
the most out of Crashlytics.
SAM EDSON: Hi.
I'm Sam Edson, another engineer on Crashlytics.
And I'm going to talk about other areas
where we've improved crash reporting for Unity developers.
We know one of the challenges of debugging IL2CPP crashes is
converting the generated C++ code back to the C# code you
wrote for your game.
We've made enhancements to IL2CPP crash
reporting to make stack traces more readable.
We call this system Stacktrace Prettification.
Marc talked previously about how we can now see C++ stack traces
for your apps.
However, one problem with raw IL2CPP stack traces is
you'll still have trouble mapping them back to our C#
code.
Well, we've introduced new smarts into our pipeline
to do that mapping for you.
So let's say you're met with this crash in your Unity game.
Normally, you'd see this stack trace.
This might be difficult to read, though,
because it involves parsing the C++ in your head.
If you look closely, you can see IL2CPP encodes a C# class
and method name in the function name.
When your crash goes through Prettification.
You get a much clearer picture of where the problem is
in the C# code you wrote.
With these changes, you can now easily
map the stack trace back to your code
and quickly diagnose issues in your game.
Now that we've covered how to easily find
the root cause in your stack trace, let's move on to how
to prioritize your crashes.
Once you start getting a lot of crashes,
you're going to need a way to know which ones are
the most important to tackle.
You can do this in Crashlytics via the issues list shown here,
which is the front page of the Crashlytics dashboard.
Previously, Unity apps were prone to an issue
we call over grouping.
Too much over grouping means unrelated crashes show up
as the same issue in this list.
In the worst case, all your crashes
will show up as one mega issue that you need to page through
to find the real issues.
This makes it hard to see whether issues
have multiple root causes or just one.
I'm excited to share that our team has been hard at work
measuring and tuning the over grouping factor for Unity apps.
So now you can tell when your crash is
rare or affecting many users.
We now cluster on more appropriate frames,
which gives you a hint for which line of your stack trace
actually caused the problem.
Also, we specifically target the C# code you write instead
of engine library code, making the stack traces even more
relevant.
And best of all, these improvements
don't just apply to crashes.
They also apply to non-fatal errors and exceptions
thrown from your game scripts.
Now let's move on to our last area of improvement,
which is Crash Metadata.
Have you ever had a problem that only impacts certain devices
or screen sizes?
For example, an issue with some graphics
cards missing a critical feature that your game depends on?
Well, developers used to log this data themselves
via Crashlytics custom keys.
And custom keys are great for adding context to your crash.
But now we're delighted to announce we'll automatically
include hardware and operating system metadata,
so you can easily look for patterns across your sessions
to debug those tricky crashes.
This helps free up your time to focus on building features
your players love.
So that concludes our talk on enhancements
to Crashlytics for Unity.
To recap, we walked through Crashlytics IL2CPP support
and multiple improvements to stack trace quality.
Then we covered how we improve grouping
for related crashes making identifying and prioritizing
issues in your app a breeze.
Lastly, we talked about additions
to crash metadata, which makes fixing tricky crashes easier.
All of this is to say debugging issues in complicated games
can be daunting.
Crashlytics is here to help you take
control of your app stability.
If you want to try out all these awesome features
navigate to firebase.google.com.
[MUSIC PLAYING]