Lesson 214: Crash Minidump Symbolicate and build_label Correlation Receipt (2026)

Direct answer: Upload symbols for each build_label, force build_label into crash metadata (or a sidecar JSON beside the minidump), symbolicate one test crash, then file crash_symbolicate_receipt_v1.json on BUILD_RECEIPT. Continues Lesson 213 telemetry—session events tell you who ran which surface; this lesson tells you which binary actually crashed.

Lesson hero for crash minidump symbolicate and build_label correlation receipt

Why this matters now (July 2026 multi-channel crash week)

July 2026 teams promote playtest, fest_public, and HTML5 lanes in the same sprint. Crash dashboards spike with identical stack hashes and no build identity—engineers chase a fix already shipped on another depot. Wednesday smoke proves boot; it does not prove symbol upload or minidump correlation.

Pair refund signal dashboard triage—players say “crash on update” while stacks show 0x00007FF… only. Lesson 212 fixes saves; this lesson fixes crash observability.

Beginner path (40-minute first symbolicate)

Step Action Success check
1 Pick symbol backend Steam / Sentry / Unity Cloud / breakpad folder
2 Upload symbols for current build_label Upload receipt ID logged
3 Inject build_label into crash payload Field visible in dashboard
4 Trigger one known test crash Minidump or report arrives
5 Open symbolicated stack Function names readable
6 File crash_symbolicate_receipt_v1.json X1–X6 pass

Time: ~40 minutes with CI symbol step; 60 minutes first Steam + Windows depot.

Developer path (gates X1–X6)

Gate Check Fail when
X1 Symbol server pin per build_label Symbols missing for fest build
X2 build_label on crash metadata Anonymous version=1.0.0 only
X3 surface matches telemetry playtest crash tagged fest_public
X4 Test minidump symbolicated Hash-only stack
X5 Symbol upload within 24h of promotion Old symbols serve new EXE
X6 crash_symbolicate_receipt_v1.json promotion_allowed: false

Symbol server pin (X1)

Document in release-evidence/crash/SYMBOL_SERVER_PIN.json:

{
  "schema": "symbol_server_pin_v1",
  "build_label": "fest-demo-2026-10-rc2",
  "engine": "unity_il2cpp",
  "backend": "steam_crash_handler",
  "symbol_upload_id": "steam-upload-2026-05-25-abc",
  "executable_sha256": "sha256:…",
  "uploaded_at_utc": "2026-05-25T18:00:00Z"
}

Godot / custom engines: pin breakpad or Sentry debug file path instead of Steam ID.

build_label on minidump (X2)

Unity IL2CPP: embed Application.version from same VERSION file as Lesson 201.

Sidecar pattern when SDK lacks fields:

{
  "schema": "crash_context_v1",
  "build_label": "fest-demo-2026-10-rc2",
  "surface": "fest_public",
  "minidump_id": "uuid-from-backend"
}

Upload sidecar with minidump or attach as crash annotation—never put Steam ID here.

Crosswalk with telemetry (X3)

Telemetry surface Crash surface Match?
fest_public fest_public required
playtest_invite fest_public fail — wrong depot

Join dashboards on build_label + surface only (Lesson 213).

Test crash protocol (X4)

Engine Test crash Pass when
Unity throw new Exception("BUILD_RECEIPT_TEST_CRASH"); in dev menu Symbolicated BUILD_RECEIPT_TEST_CRASH
Godot assert(false) behind debug flag File:line after upload
NW.js process.crash() in internal build only Never in fest_public

Strip test hook before fest promotion; receipt records test crash ID removed in production row.

crash_symbolicate_receipt_v1.json

{
  "schema": "crash_symbolicate_receipt_v1",
  "build_label": "fest-demo-2026-10-rc2",
  "symbol_server_pin": "release-evidence/crash/SYMBOL_SERVER_PIN.json",
  "test_crash": {
    "triggered": true,
    "symbolicated": true,
    "top_frame": "BUILD_RECEIPT_TEST_CRASH",
    "test_hook_removed_in_production": true
  },
  "metadata_fields": ["build_label", "surface"],
  "paired_receipts": {
    "telemetry_session": "release-evidence/telemetry/TELEMETRY_SESSION_RECEIPT.json",
    "save_slot_label": "release-evidence/saves/SAVE_SLOT_LABEL_RECEIPT.json"
  },
  "gates": {
    "X1_symbol_pin": "pass",
    "X2_build_label_metadata": "pass",
    "X3_surface_correlation": "pass",
    "X4_test_symbolicate": "pass",
    "X5_upload_freshness": "pass",
    "X6_receipt": "pass"
  },
  "promotion_allowed": true
}

Pin under release-evidence/crash/CRASH_SYMBOLICATE_RECEIPT.json.

BUILD_RECEIPT columns

Column Source
crash_symbolicate_receipt This lesson
symbol_server_pin Path + upload ID
telemetry_session_receipt Lesson 213
build_label VERSION spine

Thursday row reviewCrash row: symbolicated Y/N + build_label match.

Engine lanes

Engine Symbol artifact Upload lane
Unity IL2CPP .pdb / .so.debug Unity Cloud Diagnostics help
Godot 4.5 Export templates debug Self-hosted breakpad
GameMaker YYC debug symbols Steam crash dumps folder
Ren'Py Traceback text only Log build_label in log.txt

Proof table (crash triage week)

Reported issue build_label in stack? Symbolicated? Action
Crash after fest patch yes yes Fix top frame
Crash playtest only playtest label yes Do not patch fest yet
Hash-only stack no no Block promotion (X4)

Key takeaways

  1. Unsymbolicated stacks are not triage—they are noise during fest week.
  2. build_label must match upload logs and telemetry—not Application.version hand-typed once.
  3. Test crash before players—proves pipeline, not gameplay.
  4. Symbol freshness (X5) matters more than symbol existence from last month.
  5. Refund dashboard (215) assumes crash rows exist—ship this receipt first.
  6. Multi-channel uploads multiply crash sources—surface is mandatory.
  7. Wednesday smoke does not replace symbol upload—run both.
  8. AI dialogue hotfix (216) needs symbolicated stacks to avoid guessing.

Prerequisites

Common mistakes

  • Uploading symbols once per project, not per build_label.
  • Shipping test crash hook in fest_public.
  • Correlating crashes with Steam ID instead of build_label.
  • Skipping symbol upload on HTML5-only week (still file receipt n/a + desktop pin).
  • Chasing playtest crashes on fest branch without surface filter.

Troubleshooting

Symptom Lane
Symbol upload failed Unity symbol upload help
Wrong build in dashboard X3 + Lesson 213
Spike after promotion X5 freshness + Wednesday smoke
“Crash” = save loss Lesson 212
Bevy wasm panic without build_label Bevy crash log correlation preflight — separate from minidump X1–X6
UE menu playtest .dmp anonymous Unreal menu minidump build_label preflightM1–M6 lane

Mini exercise (60 minutes)

  1. Pin SYMBOL_SERVER_PIN.json for current fest build_label.
  2. Add build_label + surface to crash SDK init.
  3. Trigger test crash on internal build; capture symbolicated frame.
  4. Remove test hook; rebuild; confirm hook absent.
  5. File crash_symbolicate_receipt_v1.json; update BUILD_RECEIPT.

Next: Lesson 215 — refund signal dashboard receipt.

Continuity — H1 2026 arc (212–217)

Lesson Receipt focus
212 Save slot labels
213 Telemetry session
214 (this) Crash symbolicate + build_label
215 Refund dashboard
216 AI dialogue patch
217 H1 capstone

FAQ

Sentry instead of Steam?
Set backend: sentry in pin JSON; X1–X6 unchanged.

No desktop build (HTML5 only)?
File receipt with desktop_symbolicate: n/a; still require build_label on web error reports if captured.

Same stack on two build_labels?
Expected—use build_label to see which depot still ships the bug.


Symbolicate with build_label pinned—or fest crash threads stay unreadable hash soup.