Quick answer: Enable per-platform symbol generation: Android Create symbols.zip, iOS dSYM, Windows .pdb. Upload to your crash reporter so stack traces map to function names. Without this, shipping crashes are nearly impossible to debug.

Here is how to fix Unity shipping builds where crash logs show only memory offsets instead of function names. Symbolication needs the original symbol files; ensure they are generated and uploaded.

The Symptom

Crash report shows stack like libil2cpp.so + 0x4F2A8C. No function names. Cannot diagnose what crashed.

What Causes This

Stripping by default. Shipping builds strip symbols for size.

Symbols not uploaded. Even if generated, they sit in your build folder unused.

Mismatched symbol version. Symbols from build N do not symbolicate crashes from build N+1.

The Fix

Step 1: Generate symbols at build.

Android:    Build Settings -> Create symbols.zip = Public
iOS:        Xcode -> Build Settings -> Generate Debug Symbols = Yes
Windows:    Player Settings -> Configuration -> Copy PDB Files = checked

Each platform has its own toggle. Enable per platform you ship to.

Step 2: Upload to crash reporter. Sentry, Backtrace, Bugsnag, etc. all support uploading symbols. Use their CLI or Unity package to upload after each build.

# Example: Sentry upload
sentry-cli upload-dif --type=zip ./build/symbols.zip

Step 3: Tag uploads with build version. Use Application.version + Application.buildGUID to match crashes to specific symbols.

Step 4: Test with a known crash. Add a button in dev that throws a NullReferenceException. Verify your reporter shows it with C# function names.

Step 5: For Google Play Console. Upload symbols.zip via Play Console → App Bundle Explorer → Native Debug Symbols. Crash reports automatically symbolicate.

“Generate symbols. Upload symbols. Tag with version. Crash reports become readable.”

Related Issues

For IL2CPP marshaling, see IL2CPP P/Invoke. For build size, see Build Size.

Symbols at build. Upload to reporter. Versioned. Crashes solvable.